【PHP8.x】__constructメソッドの使い方

__constructメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

__constructメソッドは、ClosedGeneratorExceptionクラスの新しいインスタンスを初期化(構築)する際に自動的に実行される特別なメソッドです。このメソッドは、コンストラクタとして機能し、例外オブジェクトが作成される際に必要な情報を設定します。

ClosedGeneratorExceptionは、PHP 8で導入された例外クラスで、ジェネレーターがすでに閉じられている(つまり、これ以上値を生成できない状態になっている)にもかかわらず、そのジェネレーターに対してrewind()send()といった無効な操作が試みられた場合にスローされます。例えば、ジェネレーターが一度すべての値をyieldし終えた後や、return文で明示的に終了された後に、再度そのジェネレーターを操作しようとすると、この例外が発生します。

この__constructメソッドを通じて、開発者は例外が発生した状況を説明するメッセージや、特定の条件を示すエラーコードなどをClosedGeneratorExceptionオブジェクトに渡して設定することができます。これにより、プログラムの実行中に閉じられたジェネレーターへの不適切なアクセスが発生した際に、その原因を特定し、適切にエラー処理を行うための手がかりを得られます。基本的には、親クラスであるExceptionのコンストラクタを呼び出して、例外の基本的な属性を設定する役割を担っています。

構文(syntax)

1final public __construct()

引数(parameters)

string $message = '', int $code = 0, ?Throwable $previous = null

  • string $message: エラーメッセージを指定する文字列
  • int $code: エラーコードを指定する整数
  • ?Throwable $previous: 例外発生の原因となった前の例外オブジェクト

戻り値(return)

void

このコンストラクタは、ClosedGeneratorException オブジェクトを生成します。戻り値はありません。

サンプルコード

ClosedGeneratorException::__construct()で例外を投げる

1<?php
2
3/**
4 * ClosedGeneratorException::__construct() のサンプルコード
5 *
6 * このコードは、ClosedGeneratorException クラスのコンストラクタの
7 * 使い方を実演します。この例外は通常、PHPエンジンによって、
8 * 閉じられた(または終了した)ジェネレータに対して操作が試みられたときに
9 * 自動的にスローされます。
10 *
11 * ここでは、コンストラクタの引数 ($message, $code, $previous) の使用方法を
12 * 示すために、例外を手動でインスタンス化してスローします。
13 */
14try {
15    // 1. 以前発生した例外を模擬するオブジェクトを作成します。
16    //    これは $previous 引数に渡すことができます。
17    $previousException = new \RuntimeException("データ処理中に問題が発生しました。", 500);
18
19    // 2. ClosedGeneratorException の新しいインスタンスを生成します。
20    //    コンストラクタの引数:
21    //    - $message: 例外に関する説明メッセージ。
22    //    - $code: 例外の数値コード。
23    //    - $previous: この例外の前に発生した例外。
24    $closedGeneratorException = new \ClosedGeneratorException(
25        "ジェネレータは既に閉じられているか、終了しています。", // カスタムメッセージ
26        1001,                                              // カスタムエラーコード
27        $previousException                                // 前の例外
28    );
29
30    // 3. 生成した例外をスローして、catch ブロックで捕捉されることを示します。
31    throw $closedGeneratorException;
32
33} catch (\ClosedGeneratorException $e) {
34    // 4. ClosedGeneratorException を捕捉し、その詳細を表示します。
35    echo "--- ClosedGeneratorException を捕捉しました ---\n";
36    echo "メッセージ: " . $e->getMessage() . "\n";
37    echo "コード: " . $e->getCode() . "\n";
38    echo "ファイル: " . $e->getFile() . " (行: " . $e->getLine() . ")\n";
39
40    // 5. 以前の例外が存在する場合、その情報を表示します。
41    if ($e->getPrevious() !== null) {
42        echo "\n--- 以前の例外情報 ---\n";
43        echo "タイプ: " . get_class($e->getPrevious()) . "\n";
44        echo "メッセージ: " . $e->getPrevious()->getMessage() . "\n";
45        echo "コード: " . $e->getPrevious()->getCode() . "\n";
46    }
47} catch (\Throwable $e) {
48    // 6. その他の予期せぬ例外を捕捉します。
49    echo "--- 予期せぬ例外を捕捉しました ---\n";
50    echo "タイプ: " . get_class($e) . "\n";
51    echo "メッセージ: " . $e->getMessage() . "\n";
52}
53

このサンプルコードは、PHPのClosedGeneratorExceptionクラスのコンストラクタである__constructメソッドの基本的な使い方を解説しています。ClosedGeneratorExceptionは、閉じられた(既に処理を終えた)ジェネレータに対して何らかの操作を試みた際に、通常PHPエンジンによって自動的に発生する例外です。

__constructメソッドは、新しい例外オブジェクトを初期化する際に使用します。引数として、例外に関する詳細な説明文を指定する$message(文字列、省略可能)、例外の種類を識別するための数値コードを指定する$code(整数、省略可能)、そしてこの例外が発生する前に起こった別の例外を渡す$previousThrowableインターフェースを実装したオブジェクトまたはnull、省略可能)を受け取ります。このメソッドはオブジェクトの初期化を行うため、具体的な値を返しません(void)。

サンプルコードでは、まずRuntimeExceptionを模擬的に作成し、これを$previous引数に渡す準備をします。次に、ClosedGeneratorExceptionオブジェクトを手動でインスタンス化し、カスタムメッセージ、エラーコード、そして前の例外オブジェクトを__constructメソッドの引数として渡しています。その後、throw文でこの例外を意図的に発生させ、catchブロックで捕捉することで、設定したメッセージやコード、前の例外情報が適切に取得できることを実演しています。

ClosedGeneratorExceptionは、閉じられた(または終了した)ジェネレータへの操作時にPHPエンジンが自動でスローする例外です。サンプルコードは、この例外の__construct(コンストラクタ)の引数の使い方を説明するため、手動でインスタンスを作成しスローしています。

$message引数で具体的なエラー内容を、$code引数で独自のエラーコードを、$previous引数で根本原因となった別の例外を渡すと、エラー発生時の情報が充実し、問題の特定とデバッグが非常にしやすくなります。try-catchブロックで例外を捕捉し、getMessage()getPrevious()などのメソッドで詳細情報を取得し、適切にログに出力したりユーザーに通知したりすることが重要です。

PHP 8 コンストラクタプロパティ昇格で例外を簡潔に定義・利用する

1<?php
2
3// PHP 8 で導入された「コンストラクタプロパティ昇格 (Constructor Property Promotion)」の例です。
4// これは、コンストラクタの引数を直接クラスのプロパティとして定義・初期化する便利な機能です。
5// ClosedGeneratorException のコンストラクタ引数と同じシグネチャを持つカスタム例外クラスを定義し、
6// プロパティ昇格を使ってシンプルに初期化する方法を示します。
7
8/**
9 * ClosedGeneratorException のコンストラクタ引数シグネチャを模倣したカスタム例外クラス。
10 * PHP 8 のコンストラクタプロパティ昇格を利用して、プロパティの定義と初期化を簡略化しています。
11 */
12class MyCustomException extends Exception
13{
14    /**
15     * 新しいカスタム例外インスタンスを作成します。
16     *
17     * コンストラクタの引数に `public`, `protected`, `private` のアクセス修飾子を付けることで、
18     * 自動的にその名前と型のプロパティがクラスに定義され、引数の値で初期化されます。
19     * これがコンストラクタプロパティ昇格の主な特徴です。
20     *
21     * @param string $message 例外のメッセージ。
22     * @param int $code 例外コード。
23     * @param ?Throwable $previous 以前に発生した例外オブジェクト (例外チェイン用)。
24     */
25    public function __construct(
26        public string $message = '',
27        public int $code = 0,
28        public ?Throwable $previous = null
29    ) {
30        // 親クラス (Exception) のコンストラクタを呼び出す必要があります。
31        // プロパティ昇格によって $this->message, $this->code, $this->previous は既に初期化されています。
32        parent::__construct($this->message, $this->code, $this->previous);
33    }
34
35    /**
36     * カスタムエラーメッセージを生成するヘルパーメソッド。
37     */
38    public function getCustomFormattedMessage(): string
39    {
40        $formattedMessage = "カスタムエラー発生: " . $this->message;
41        if ($this->code !== 0) {
42            $formattedMessage .= " (コード: " . $this->code . ")";
43        }
44        if ($this->previous !== null) {
45            $formattedMessage .= " [以前の例外: " . get_class($this->previous) . " - " . $this->previous->getMessage() . "]";
46        }
47        return $formattedMessage;
48    }
49}
50
51// --- カスタム例外の使用例 ---
52
53echo "--- 基本的な例外の使用例 ---" . PHP_EOL;
54try {
55    // プロパティ昇格で定義されたMyCustomExceptionをスローします。
56    throw new MyCustomException("ファイルが見つかりませんでした", 404);
57} catch (MyCustomException $e) {
58    // 例外をキャッチし、プロパティに直接アクセスして情報を取得します。
59    echo "キャッチされた例外: " . get_class($e) . PHP_EOL;
60    echo "メッセージ (プロパティ): " . $e->message . PHP_EOL; // $e->message で直接アクセス
61    echo "コード (プロパティ): " . $e->code . PHP_EOL;       // $e->code で直接アクセス
62    echo "フォーマットされたメッセージ: " . $e->getCustomFormattedMessage() . PHP_EOL;
63    echo "標準のgetMessage(): " . $e->getMessage() . PHP_EOL;
64    echo "標準のgetCode(): " . $e->getCode() . PHP_EOL;
65}
66
67echo PHP_EOL . "--- 例外チェインの使用例 ---" . PHP_EOL;
68try {
69    // 内部で別の例外が発生し、それをMyCustomExceptionにラップします。
70    try {
71        // 意図的にエラーを発生させる
72        $result = 10 / 0; // DivisionByZeroError が発生
73    } catch (DivisionByZeroError $innerException) {
74        // 発生したエラーを$previous引数としてMyCustomExceptionに渡します。
75        throw new MyCustomException("計算処理中にエラーが発生しました", 500, $innerException);
76    }
77} catch (MyCustomException $e) {
78    echo "キャッチされた例外: " . get_class($e) . PHP_EOL;
79    echo "メッセージ: " . $e->message . PHP_EOL;
80    echo "コード: " . $e->code . PHP_EOL;
81    // 以前の例外 ($previousプロパティ) が存在するか確認し、情報を表示します。
82    if ($e->previous !== null) {
83        echo "以前の例外タイプ: " . get_class($e->previous) . PHP_EOL;
84        echo "以前の例外メッセージ: " . $e->previous->getMessage() . PHP_EOL;
85        echo "以前の例外コード: " . $e->previous->getCode() . PHP_EOL;
86    }
87    echo "フォーマットされたメッセージ: " . $e->getCustomFormattedMessage() . PHP_EOL;
88}
89

PHPのClosedGeneratorExceptionは、閉じられたジェネレータオブジェクトに対して操作を行おうとした際に発生する内部例外クラスです。そのコンストラクタである__constructメソッドは、この例外のインスタンスを初期化するために用いられます。引数には、例外の詳細を伝える文字列型の$message、例外の種類を示す整数型の$code、そしてこの例外が発生する前の原因となった別の例外オブジェクトを渡すための?Throwable $previousを受け取ります。これらはすべて省略可能で、それぞれ空文字、0、nullがデフォルト値です。このメソッドは、インスタンスを生成するのみでvoidを返します。

提供されたサンプルコードでは、PHP 8で導入された「コンストラクタプロパティ昇格」という機能を利用して、ClosedGeneratorExceptionのコンストラクタシグネチャを模倣したカスタム例外クラスMyCustomExceptionを簡潔に定義しています。この機能は、コンストラクタの引数にpublicなどのアクセス修飾子を記述するだけで、クラスのプロパティを自動的に宣言し、その引数の値で初期化できるため、冗長なプロパティ定義と代入の記述を省略できます。

コードでは、MyCustomExceptionのインスタンスをthrowで発生させ、try-catchブロックで捕捉する一般的な例外処理のパターンを示しています。捕捉した例外オブジェクトの$message$codeといった情報は、プロパティとして直接アクセスできるため、例外の内容を簡単に取得・処理できます。また、$previous引数を利用した例外チェインの例も含まれており、複数の例外が連鎖して発生した場合の原因追跡に役立つ利用方法が示されています。

サンプルコードは、PHP 8で導入されたコンストラクタプロパティ昇格の活用例です。これは、コンストラクタ引数にアクセス修飾子を付けるだけでプロパティ定義と初期化が同時に行える便利な機能です。親クラスのコンストラクタを呼び出す際は、昇格された$this->messageなどのプロパティを利用できますが、呼び出し自体を忘れないように注意してください。例外処理では、try-catchで例外を捕捉した後、昇格されたプロパティに直接アクセスして情報を取り出します。$previous引数を使った例外チェインは、元の例外の詳細情報を保持したまま、新しい例外として扱うために重要です。これにより、エラーの原因特定がしやすくなります。