【PHP8.x】LengthException::__construct()メソッドの使い方
__constructメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
__constructメソッドは、LengthExceptionオブジェクトが生成される際に、そのインスタンスを初期化するために実行されるメソッドです。このメソッドはコンストラクタとして機能し、長さに関するエラーが発生したことを示す例外オブジェクトに、具体的なエラー情報を持たせる役割を担います。通常、このメソッドはプログラマがコード内で明示的に throw new LengthException(...) という構文を使って例外をスローする際に呼び出されます。引数として、エラーの内容を説明するメッセージ文字列、エラー種別を識別するための整数コード、そして先行する例外(例外チェーンを形成する場合)を指定できます。第一引数のメッセージは、デバッグ時にエラーの原因を特定するための重要な情報となります。第二引数のコードは、catchブロックで例外を捕捉した際に、コードの値に応じて処理を分岐させるために利用されます。このように、__constructメソッドは、長さに関するロジックエラーの詳細をオブジェクトに設定し、堅牢なエラーハンドリングを実現するための基礎となります。
構文(syntax)
1new LengthException(string $message = "", int $code = 0, ?Throwable $previous = null);
引数(parameters)
string $message = "", int $code = 0, ?Throwable $previous = null
- string $message: 例外発生時に表示されるエラーメッセージを指定する文字列です。
- int $code: 例外に付与されるエラーコードを指定する整数です。
- ?Throwable $previous: この例外が発生する原因となった以前の例外を指定します。
nullの場合は前の例外がありません。
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP 8コンストラクタプロモーションでカスタム例外を実装する
1<?php 2 3/** 4 * ユーザー名の長さが不正な場合にスローされる独自の例外クラス。 5 * LengthExceptionを継承し、PHP 8.0の新機能である「コンストラクタプロモーション」を利用します。 6 */ 7class InvalidUsernameException extends LengthException 8{ 9 /** 10 * コンストラクタ 11 * 12 * キーワード「コンストラクタプロモーション」の利用例です。 13 * 引数に `public readonly string $invalidUsername` と可視性(public)や修飾子(readonly)を付けるだけで、 14 * 同名のプロパティが自動的に宣言され、コンストラクタの引数が代入されます。 15 * 16 * 従来の書き方: 17 * public readonly string $invalidUsername; 18 * public function __construct(string $invalidUsername, ...) { 19 * $this->invalidUsername = $invalidUsername; 20 * parent::__construct(...); 21 * } 22 * これが1行で簡潔に記述できます。 23 * 24 * @param string $invalidUsername 検証に失敗したユーザー名。この値が同名の公開プロパティにセットされます。 25 * @param string $message 親クラスに渡す例外メッセージ。 26 * @param int $code 親クラスに渡す例外コード。 27 * @param ?Throwable $previous 親クラスに渡す直前の例外。 28 */ 29 public function __construct( 30 public readonly string $invalidUsername, 31 string $message = "", 32 int $code = 0, 33 ?Throwable $previous = null 34 ) { 35 // 親クラスである LengthException のコンストラクタを呼び出します。 36 parent::__construct($message, $code, $previous); 37 } 38} 39 40/** 41 * 指定されたユーザー名の長さを検証する関数。 42 * 43 * @param string $username 検証するユーザー名。 44 * @throws InvalidUsernameException ユーザー名の長さが4文字未満または10文字より大きい場合。 45 */ 46function validateUsername(string $username): void 47{ 48 $length = mb_strlen($username); 49 if ($length < 4 || $length > 10) { 50 // 長さが不正な場合、カスタム例外をスローします。 51 throw new InvalidUsernameException( 52 $username, // コンストラクタプロモーションで定義されたプロパティ `$invalidUsername` に渡される値 53 "ユーザー名は4文字以上10文字以下にしてください。" 54 ); 55 } 56 echo "ユーザー名 '{$username}' は有効です。" . PHP_EOL; 57} 58 59// --- メイン処理 --- 60try { 61 // わざと短すぎるユーザー名を指定して、例外を発生させます。 62 validateUsername("Joe"); 63} catch (InvalidUsernameException $e) { 64 // InvalidUsernameException をキャッチします。 65 echo "エラーをキャッチしました。" . PHP_EOL; 66 // 親クラス(Exception)から継承したメソッドでメッセージを取得します。 67 echo " メッセージ: " . $e->getMessage() . PHP_EOL; 68 // コンストラクタプロモーションによって設定された公開プロパティにアクセスします。 69 echo " 不正な入力値: " . $e->invalidUsername . PHP_EOL; 70}
LengthExceptionクラスの__constructメソッドは、このクラスのインスタンスを生成する際に自動的に呼び出されるコンストラクタです。主に、長さに関するエラーが発生した際の詳細情報であるエラーメッセージやエラーコードなどを初期化する役割を担います。
サンプルコードでは、LengthExceptionを継承してInvalidUsernameExceptionという独自の例外クラスを定義しています。これにより、「ユーザー名の長さが不正」という、より具体的なエラー状況を扱うことができます。
このコードの最大の特徴は、PHP 8の新機能「コンストラクタプロモーション」を利用している点です。コンストラクタの引数で public readonly string $invalidUsername のように可視性や型を宣言するだけで、同名のプロパティが自動的に定義され、引数の値が代入されます。これにより、従来よりもコードを大幅に簡潔に記述できます。
InvalidUsernameExceptionのコンストラクタは、不正なユーザー名を独自のプロパティに格納しつつ、parent::__construct() を呼び出して、受け取ったエラーメッセージなどを親クラスであるLengthExceptionに渡して処理を委ねています。
引数$messageはエラーメッセージ、$codeはエラーコード、$previousは例外が連鎖する場合の直前の例外オブジェクトを指定します。コンストラクタのため、このメソッドに戻り値はありません。
PHP 8.0から導入されたコンストラクタプロモーションは、プロパティの宣言と初期化を同時に行える便利な機能です。サンプルコードのように独自の例外クラスで利用する際は、親クラスのコンストラクタ parent::__construct() を必ず呼び出してください。これを忘れると、例外メッセージなどが正しく設定されません。また、プロモーションを適用する引数には public などの可視性を付ける必要があります。可視性がないと、単なるローカル変数として扱われ、プロパティは作成されないので注意が必要です。なお、サンプルで併用されている readonly は、一度代入すると変更できなくなるプロパティを定義するPHP 8.1からの機能です。このため、コードを実行するにはPHP 8.1以上の環境が必要となります。
PHP 8.0 コンストラクタプロパティプロモーションでカスタム例外を実装する
1<?php 2 3/** 4 * LengthExceptionを継承したカスタム例外クラスです。 5 * ユーザー名の長さが不正な場合にスローされます。 6 */ 7class InvalidUsernameLengthException extends LengthException 8{ 9 /** 10 * PHP 8.0の新機能「コンストラクタプロパティプロモーション」を使用しています。 11 * コンストラクタの引数に可視性(public, protected, private)を指定することで、 12 * プロパティの宣言とコンストラクタ内での値の代入を同時に行うことができます。 13 * 14 * @param string $username 検証に失敗したユーザー名 15 * @param int $minLength 許容される最小文字数 16 * @param int $maxLength 許容される最大文字数 17 * @param string $message 例外メッセージ 18 * @param int $code 例外コード 19 * @param ?Throwable $previous 前の例外 20 */ 21 public function __construct( 22 public readonly string $username, 23 public readonly int $minLength, 24 public readonly int $maxLength, 25 string $message = "", 26 int $code = 0, 27 ?Throwable $previous = null 28 ) { 29 // 親クラスであるLengthExceptionのコンストラクタを呼び出します。 30 // メッセージが指定されていない場合は、ここで動的に生成します。 31 if ($message === "") { 32 $message = "ユーザー名 '{$this->username}' は{$this->minLength}〜{$this->maxLength}文字で入力してください。"; 33 } 34 parent::__construct($message, $code, $previous); 35 } 36} 37 38/** 39 * ユーザー名の長さを検証し、不正な場合にカスタム例外をスローする関数です。 40 * 41 * @param string $username 検証するユーザー名 42 * @throws InvalidUsernameLengthException ユーザー名の長さが不正な場合 43 */ 44function validateUsernameLength(string $username): void 45{ 46 $minLength = 4; 47 $maxLength = 16; 48 $actualLength = mb_strlen($username); 49 50 if ($actualLength < $minLength || $actualLength > $maxLength) { 51 // 長さが不正な場合、カスタム例外をスローします。 52 // コンストラクタプロパティプロモーションにより、引数を渡すだけでプロパティが初期化されます。 53 throw new InvalidUsernameLengthException($username, $minLength, $maxLength); 54 } 55 56 echo "ユーザー名 '{$username}' は有効です。" . PHP_EOL; 57} 58 59// --- 実行コード --- 60try { 61 validateUsernameLength('php_developer'); // 正常なケース 62 validateUsernameLength('ng'); // 例外がスローされるケース 63} catch (InvalidUsernameLengthException $e) { 64 // スローされたカスタム例外をキャッチします。 65 echo "エラー: " . $e->getMessage() . PHP_EOL; 66 // カスタム例外クラスで定義したプロパティに直接アクセスできます。 67 echo "入力されたユーザー名: " . $e->username . PHP_EOL; 68 echo "許容文字数: " . $e->minLength . "〜" . $e->maxLength . "文字" . PHP_EOL; 69}
このサンプルコードは、PHPの組み込み例外クラスLengthExceptionを継承し、ユーザー名の文字数検証に特化した独自の例外クラスInvalidUsernameLengthExceptionを定義する例です。
LengthExceptionのコンストラクタ__constructは、例外に関する情報として、エラーメッセージの$message、エラーコードの$code、そして直前の例外を示す$previousを引数に取ります。
このカスタム例外クラスでは、PHP 8.0の新機能「コンストラクタプロパティプロモーション」が活用されています。コンストラクタの引数にpublic readonlyのようなアクセス修飾子を付けることで、クラスのプロパティ宣言と、コンストラクタ内での値の代入を同時に、かつ簡潔に記述できます。これにより、検証に失敗したユーザー名などの追加情報を、例外オブジェクトが直接保持できるようになります。
クラス内部では、parent::__construct()を呼び出すことで親クラスであるLengthExceptionのコンストラクタを実行し、例外としての基本的な機能を初期化しています。コンストラクタはオブジェクトを初期化するための特別なメソッドであり、戻り値はありません。この仕組みにより、エラー発生時に、より具体的で詳細な情報を含んだ例外をスローすることが可能になります。
このコードで使われているコンストラクタプロパティプロモーションは、PHP 8.0から導入された構文です。コンストラクタの引数にpublicなどの可視性修飾子を付けることで、プロパティ宣言と初期化を同時に行います。修飾子を付け忘れるとプロパティにならないため注意してください。また、readonlyはPHP 8.1からの機能で、一度初期化した値を変更できなくなり安全性が向上します。親クラスを継承している場合、parent::__construct()を呼び出して親の初期化処理を忘れずに行うことが重要です。これを怠ると、例外メッセージなどが正しく設定されない原因となります。独自のプロパティを持つことで、エラー発生時の詳細な情報をcatchブロックで簡単に取得できます。