【PHP8.x】BadFunctionCallException::__construct()メソッドの使い方
__constructメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
__constructメソッドは、BadFunctionCallExceptionクラスの新しいインスタンスを生成し、初期化する処理を実行するメソッドです。BadFunctionCallExceptionは、無効なコールバック関数が指定された場合や、関数呼び出し時に必須の引数が不足している場合など、関数呼び出しに関する構造的な問題が発生した際にスローされる例外です。このコンストラクタは、例外オブジェクトが生成される際に自動的に呼び出されます。引数として、例外の理由を説明するエラーメッセージ、例外を識別するための整数コード、そしてこの例外が別の例外によって引き起こされた場合にその原因となった前の例外オブジェクトをそれぞれ受け取ることができます。これらの引数を通じて、例外発生時の詳細な状況をオブジェクトのプロパティとして設定します。このメソッドは親クラスであるLogicExceptionから継承されており、PHPの標準的な例外処理の仕組みに則って一貫した方法で例外オブジェクトを生成するために使用されます。これにより、開発者は関数呼び出しのエラー情報を正確に表現した例外オブジェクトを作成し、適切に処理することが可能になります。
構文(syntax)
1public __construct(string $message = "", int $code = 0, ?Throwable $previous = null)
引数(parameters)
string $message = "", int $code = 0, ?Throwable $previous = null
- string $message: 発生した問題の説明を示す文字列。
- int $code: 例外のコードを指定する整数。
- ?Throwable $previous: この例外の原因となった以前のスロー可能オブジェクト(例外)。
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP8コンストラクタプロパティプロモーションで例外を扱う
1<?php 2 3declare(strict_types=1); 4 5/** 6 * コンストラクタプロパティプロモーションを説明するためのカスタム例外クラス。 7 * 8 * PHP 8.0で導入されたこの機能を使うと、コンストラクタの引数リストで 9 * プロパティの宣言と初期化を同時に行うことができ、コードが簡潔になります。 10 */ 11class CustomException extends Exception 12{ 13 // コンストラクタプロパティプロモーションの使用例。 14 // 引数の前に `public` などの可視性修飾子を付けると、 15 // 同名のプロパティが自動的に宣言され、コンストラクタの引数が代入されます。 16 // ここでは `$context` プロパティをそのように定義しています。 17 public function __construct( 18 string $message = "", 19 public readonly ?array $context = null, // この行がプロパティプロモーションです 20 int $code = 0, 21 ?Throwable $previous = null 22 ) { 23 // 親クラスである Exception のコンストラクタを呼び出します。 24 parent::__construct($message, $code, $previous); 25 } 26} 27 28try { 29 // 例外を意図的にスローします。 30 // `context` に渡した配列は、CustomException オブジェクトの 31 // public プロパティ `$context` に自動的にセットされます。 32 throw new CustomException( 33 message: "処理中に予期せぬエラーが発生しました。", 34 context: ['userId' => 123, 'operation' => 'update'] 35 ); 36} catch (CustomException $e) { 37 // 捕捉した例外の情報を出力します。 38 echo "エラーメッセージ: " . $e->getMessage() . PHP_EOL; 39 echo "エラーコード: " . $e->getCode() . PHP_EOL; 40 41 // コンストラクタプロパティプロモーションによって設定されたプロパティにアクセスできます。 42 if ($e->context !== null) { 43 echo "関連情報 (コンテキスト):" . PHP_EOL; 44 foreach ($e->context as $key => $value) { 45 echo " - {$key}: {$value}" . PHP_EOL; 46 } 47 } 48}
__constructは、クラスから新しいオブジェクトを生成する際に自動的に呼び出される、コンストラクタという特別なメソッドです。このメソッドの役割は、オブジェクトが持つプロパティ(データ)を初期化することです。BadFunctionCallExceptionのような例外クラスでは、コンストラクタは主に3つの引数を取ります。第一引数$messageにはエラー内容を示す文字列を、第二引数$codeにはエラーの種類を識別するための整数を、第三引数$previousには連鎖する前の例外オブジェクトを指定します。これらは例外オブジェクトの基本的な情報を設定するために使われます。コンストラクタはオブジェクトの初期化が目的のため、特定の値を返さず、戻り値はありません。
このサンプルコードでは、PHP 8で導入された「コンストラクタプロパティプロモーション」という機能を使っています。これは、コンストラクタの引数にpublicのようなアクセス修飾子を付けるだけで、プロパティの宣言と値の代入を同時に行える構文です。コード内のpublic readonly ?array $contextがそれにあたり、$contextというプロパティを自動で作成し、引数で受け取った値をセットします。これにより、クラス定義が簡潔になります。try...catch構文では、この方法で設定された$contextプロパティにアクセスし、エラーに関する付加的な情報を取得しています。
コンストラクタプロパティプロモーションはPHP 8.0から導入された機能です。この機能を利用するには、コンストラクタの引数にpublic、protected、privateいずれかの可視性修飾子を必ず付ける必要があります。修飾子を付け忘れると、プロパティは自動生成されず、その引数はコンストラクタ内でのみ有効なローカル変数として扱われるため注意が必要です。また、Exceptionクラスを継承する場合、parent::__construct()を呼び出さないと親クラスの機能が正しく初期化されません。サンプルで使われているreadonlyはPHP 8.1からの機能で、一度初期化すると再代入できなくなり、意図しない変更を防ぐことでコードの安全性を高めます。
PHPカスタム例外の__constructとparent::__construct
1<?php 2 3declare(strict_types=1); 4 5/** 6 * 不正なAPI呼び出しを表すカスタム例外クラス。 7 * BadFunctionCallExceptionを継承して作成します。 8 */ 9class InvalidAPICallException extends BadFunctionCallException 10{ 11 /** 12 * 例外オブジェクトを構築します。 13 * 14 * このコンストラクタは、受け取った引数を使ってエラーメッセージを組み立て、 15 * parent::__construct() を呼び出して親クラス(BadFunctionCallException)の 16 * コンストラクタに処理を引き継ぎます。 17 * これにより、PHP標準の例外クラスと同様の機能を持つカスタム例外が作成できます。 18 * 19 * @param string $functionName 呼び出された無効な関数名 20 * @param int $code ユーザー定義の例外コード 21 * @param ?Throwable $previous 直前にスローされた例外(例外チェーン用) 22 */ 23 public function __construct(string $functionName, int $code = 0, ?Throwable $previous = null) 24 { 25 // 親クラスに渡すためのエラーメッセージを生成 26 $message = "無効なAPI関数 '{$functionName}' が呼び出されました。"; 27 28 // parent::__construct() を使い、親クラスのコンストラクタを呼び出す 29 parent::__construct($message, $code, $previous); 30 } 31} 32 33/** 34 * API呼び出しをシミュレートする関数。 35 * サポートされていない関数が指定された場合にカスタム例外をスローします。 36 * 37 * @param string $functionName 呼び出すAPI関数名 38 * @throws InvalidAPICallException 関数がサポートされていない場合 39 */ 40function callApi(string $functionName): void 41{ 42 $supportedFunctions = ['getUser', 'updateUser']; 43 44 if (!in_array($functionName, $supportedFunctions, true)) { 45 // サポートされていない関数が指定されたら、カスタム例外をスローする 46 throw new InvalidAPICallException($functionName, 404); 47 } 48 49 echo "API関数 '{$functionName}' は正常に実行されました。\n"; 50} 51 52// 例外処理のデモンストレーション 53try { 54 callApi('getUser'); 55 // わざと例外を発生させる 56 callApi('deleteUser'); 57} catch (InvalidAPICallException $e) { 58 // スローされた例外をキャッチし、その情報を表示する 59 echo "エラーが発生しました: " . $e->getMessage() . "\n"; 60 echo "エラーコード: " . $e->getCode() . "\n"; 61 echo "発生ファイル: " . $e->getFile() . " (" . $e->getLine() . "行目)\n"; 62}
このサンプルコードは、PHPの組み込み例外クラスであるBadFunctionCallExceptionを継承して、独自の例外クラスInvalidAPICallExceptionを作成する例です。
__constructは、クラスから新しいオブジェクトが生成されるときに自動的に呼び出される特別なメソッドで、「コンストラクタ」と呼ばれます。このカスタム例外クラスのコンストラクタは、引数として受け取った関数名$functionNameなどを用いて、独自の分かりやすいエラーメッセージを組み立てています。
ここで最も重要なのがparent::__construct()の呼び出しです。parentキーワードは親クラス(この場合はBadFunctionCallException)を指します。この記述により、自身で生成したエラーメッセージ$message、エラーコード$code、そして例外チェーンのための$previousを、親クラスのコンストラクタに渡しています。このコンストラクタ自体に戻り値はありません。
これにより、PHPの標準的な例外が持つ機能(エラーメッセージの保持、発生箇所の追跡など)をすべて引き継ぎながら、アプリケーション固有の例外処理を実装できます。コードの最後では、実際にこのカスタム例外を発生させ、catchブロックでその情報を表示しています。
このサンプルコードは、PHP標準の例外クラスを継承して独自の例外を作成する例です。最も重要な注意点は、子クラスのコンストラクタ内で parent::__construct() を呼び出すことです。これを忘れると、親クラスが持つエラーメッセージやコードなどの情報が正しく設定されず、getMessage() といったメソッドが期待通りに動作しません。parent::__construct() に渡す引数は、親クラスの定義(メッセージ、コード、前の例外)に型と順番を合わせる必要があります。このように親の機能を正しく呼び出すことで、PHPの例外処理の仕組みに則った、信頼性の高いカスタム例外を実装できます。