【PHP8.x】DomainException::codeプロパティの使い方
codeプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『codeプロパティは、スローされた例外に関する整数値のコードを保持するプロパティです。このプロパティはDomainExceptionクラスが直接定義しているものではなく、PHPの全ての例外クラスの元となるExceptionクラスから継承されています。例外がスローされる際、コンストラクタの第2引数として任意の整数値を指定することで、このcodeプロパティに値を設定できます。例外コードを指定しなかった場合、デフォルト値として0が設定されます。このプロパティの主な目的は、catchブロックで例外を捕捉した際に、エラーメッセージの文字列だけでなく、数値によってエラーの種類をプログラム的に識別することです。例えば、同じDomainExceptionであっても、codeの値が1の場合は「値が小さすぎる」、2の場合は「値が大きすぎる」といったように処理を分岐させることが可能になります。これにより、より詳細で柔軟なエラーハンドリングを実装でき、アプリケーションの堅牢性を高めるのに役立ちます。
構文(syntax)
1<?php 2 3try { 4 // 第2引数にエラーコードを指定して例外をスローします。 5 throw new DomainException("値が不正です。", 400); 6} catch (DomainException $e) { 7 // getCode()メソッドを使って、例外のコードを取得します。 8 $errorCode = $e->getCode(); 9 echo $errorCode; // 400 が出力されます。 10}
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
DomainException クラスの code プロパティは、例外が発生した際の識別コードを表す整数値を返します。
サンプルコード
CodeIgniter PHPでDomainExceptionのコードを扱う
1<?php 2 3declare(strict_types=1); 4 5/** 6 * このサンプルは、CodeIgniterのモデルクラスにおけるバリデーション処理を模倣しています。 7 * ビジネスロジックのルール(ドメイン)に違反した場合に DomainException を使用し、 8 * その `code` プロパティを使ってエラーの種類を識別する方法を示します。 9 */ 10class UserModel 11{ 12 // エラーコードを定数として定義すると、コードの可読性と保守性が向上します。 13 public const ERROR_USERNAME_TOO_SHORT = 1001; 14 public const ERROR_INVALID_CHARACTERS = 1002; 15 16 /** 17 * ユーザー名を検証し、登録処理をシミュレートします。 18 * 19 * @param string $username 検証するユーザー名 20 * @throws DomainException ユーザー名が検証ルールに違反した場合 21 */ 22 public function validateAndRegister(string $username): void 23 { 24 // ルール1: ユーザー名は4文字以上であること 25 if (mb_strlen($username) < 4) { 26 // 例外をスローする際、第2引数にエラーコードを指定します。 27 throw new DomainException( 28 'ユーザー名は4文字以上で指定してください。', 29 self::ERROR_USERNAME_TOO_SHORT 30 ); 31 } 32 33 // ルール2: ユーザー名は英数字のみで構成されること 34 if (!ctype_alnum($username)) { 35 throw new DomainException( 36 'ユーザー名には英数字以外使用できません。', 37 self::ERROR_INVALID_CHARACTERS 38 ); 39 } 40 41 // 本来はここでデータベースへの登録処理などが行われます。 42 echo "ユーザー '{$username}' は正常に検証されました。" . PHP_EOL; 43 } 44} 45 46/** 47 * CodeIgniterのコントローラーのアクションメソッドを模倣した実行部分です。 48 * UserModel を利用してユーザー登録処理を試み、発生した例外を処理します。 49 */ 50function attemptUserRegistration(): void 51{ 52 $userModel = new UserModel(); 53 // さまざまなパターンのユーザー名でテストします。 54 $testUsernames = ['ui', 'user-name', 'validUser123']; 55 56 foreach ($testUsernames as $username) { 57 echo "--- [{$username}] の登録処理を開始 ---" . PHP_EOL; 58 try { 59 $userModel->validateAndRegister($username); 60 echo "結果: 成功" . PHP_EOL; 61 } catch (DomainException $e) { 62 // DomainException をキャッチします。 63 echo "エラーメッセージ: " . $e->getMessage() . PHP_EOL; 64 65 // getCode() メソッドで例外に設定された整数コードを取得します。 66 // これはパブリックプロパティ `$e->code` に直接アクセスするのと同じ値です。 67 $errorCode = $e->getCode(); 68 echo "エラーコード: " . $errorCode . PHP_EOL; 69 70 // エラーコードに応じて、ユーザーへのフィードバックや処理を分岐させます。 71 switch ($errorCode) { 72 case UserModel::ERROR_USERNAME_TOO_SHORT: 73 echo "対応策: ユーザーに入力文字数が足りないことを通知します。" . PHP_EOL; 74 break; 75 case UserModel::ERROR_INVALID_CHARACTERS: 76 echo "対応策: ユーザーに使用できない文字が含まれていることを通知します。" . PHP_EOL; 77 break; 78 default: 79 echo "対応策: 想定外のエラーとしてログに記録します。" . PHP_EOL; 80 break; 81 } 82 } finally { 83 echo "--- [{$username}] の登録処理を終了 ---" . PHP_EOL . PHP_EOL; 84 } 85 } 86} 87 88// サンプルコードの実行 89attemptUserRegistration();
DomainExceptionが持つcodeプロパティは、発生した例外の種類を識別するための整数値を格納します。このプロパティの値は、DomainExceptionオブジェクトを生成する際のコンストラクタの第2引数に整数(エラーコード)を指定することで設定されます。
このサンプルコードは、CodeIgniterのようなフレームワークにおけるモデルの処理を模倣しています。UserModelクラスでは、ユーザー名の検証ルールに違反した場合にDomainExceptionをスローしています。その際、「文字数が不足している」場合と「不正な文字が含まれている」場合とで、それぞれ異なるエラーコード(1001と1002)をcodeプロパティに設定しています。
呼び出し側ではtry...catch構文でDomainExceptionを捕捉します。catchブロック内では、getCode()メソッドを使って例外に設定されたエラーコードを取得できます。このメソッドは引数を取らず、戻り値としてint型のコード番号を返します。サンプルでは、取得したエラーコードをswitch文で評価し、コードの値に応じて「文字数が足りない」「使用できない文字が含まれている」といった、より具体的で適切なエラーハンドリングを行っています。このようにcodeプロパティを利用することで、エラーメッセージの文字列に頼らず、機械的にエラーの種類を判別して処理を分岐させることが可能になります。
このサンプルコードは、プログラムの文法エラーではなく、ビジネス上のルール(ドメインロジック)に違反した場合に DomainException を使用する良い例です。注意点として、エラーの種類を判別する際は、変更される可能性のあるエラーメッセージの文字列ではなく、code プロパティで取得できる整数値を使うことが重要です。これにより、メッセージの文言修正に影響されない堅牢なエラー処理が実現できます。また、1001 のような数値を直接書くのではなく、ERROR_USERNAME_TOO_SHORT のような意味のある名前の定数を定義することで、コードの可読性と保守性が格段に向上します。catch で特定の例外クラスを指定することで、意図したエラーだけを的確に捕捉できる点も覚えておきましょう。
PHPでDomainExceptionとエラーコードを扱う
1<?php 2 3declare(strict_types=1); 4 5/** 6 * ユーザー名の検証を行い、規約違反の場合はDomainExceptionをスローするクラス 7 * 8 * PHP CodeSniffer (phpcs) などのツールでチェックされるような、 9 * PSR-12 コーディングスタイル規約に準拠して記述されています。 10 */ 11class UsernameValidator 12{ 13 // エラーコードを定数として定義し、可読性を高める 14 private const CODE_TOO_SHORT = 1001; 15 private const CODE_TOO_LONG = 1002; 16 private const CODE_INVALID_CHARS = 1003; 17 18 // 検証ルールを定数で定義 19 private const MIN_LENGTH = 4; 20 private const MAX_LENGTH = 12; 21 22 /** 23 * ユーザー名を検証します。 24 * 25 * 値が定義されたドメイン(有効な値の集合)に属していない場合、 26 * 問題の種類に応じたエラーコードを持つ DomainException をスローします。 27 * 28 * @param string $username 検証するユーザー名 29 * @throws DomainException ユーザー名が検証ルールに違反した場合 30 */ 31 public static function validate(string $username): void 32 { 33 if (mb_strlen($username) < self::MIN_LENGTH) { 34 throw new DomainException( 35 "ユーザー名は " . self::MIN_LENGTH . " 文字以上である必要があります。", 36 self::CODE_TOO_SHORT 37 ); 38 } 39 40 if (mb_strlen($username) > self::MAX_LENGTH) { 41 throw new DomainException( 42 "ユーザー名は " . self::MAX_LENGTH . " 文字以下である必要があります。", 43 self::CODE_TOO_LONG 44 ); 45 } 46 47 // 半角英数字のみを許可する正規表現 48 if (!preg_match('/^[a-zA-Z0-9]+$/', $username)) { 49 throw new DomainException( 50 "ユーザー名には半角英数字のみ使用できます。", 51 self::CODE_INVALID_CHARS 52 ); 53 } 54 } 55} 56 57// 検証するユーザー名のリスト 58$testUsernames = [ 59 'ok_user', // 正常 60 'ng', // 短すぎる 61 'too_long_username_example', // 長すぎる 62 'ng-user', // 不正な文字 63]; 64 65// 各ユーザー名をループで検証 66foreach ($testUsernames as $username) { 67 echo "--- 検証中: '{$username}' ---" . PHP_EOL; 68 try { 69 // 検証処理を呼び出す 70 UsernameValidator::validate($username); 71 echo "結果: 検証OKです。" . PHP_EOL; 72 } catch (DomainException $e) { 73 // 例外をキャッチし、メッセージとコードを取得して表示 74 // $e->getCode() で例外に設定された整数値を取得できる 75 $errorCode = $e->getCode(); 76 echo "エラー発生: " . $e->getMessage() . PHP_EOL; 77 echo "エラーコード: " . $errorCode . PHP_EOL; 78 79 // エラーコードに基づいて、より具体的な処理を分岐させることも可能 80 switch ($errorCode) { 81 case 1001: 82 echo "対応: 入力文字数を増やしてください。" . PHP_EOL; 83 break; 84 case 1002: 85 echo "対応: 入力文字数を減らしてください。" . PHP_EOL; 86 break; 87 case 1003: 88 echo "対応: 使用できない文字を削除してください。" . PHP_EOL; 89 break; 90 } 91 } 92 echo PHP_EOL; 93}
このPHPサンプルコードは、例外処理におけるDomainExceptionのcodeプロパティの使用方法を示しています。codeは例外に固有のエラーコード(整数値)を格納するためのプロパティで、Exceptionクラスから継承されたものです。
コードでは、ユーザー名を検証するUsernameValidatorクラスが定義されています。このクラスは、ユーザー名が「短すぎる」「長すぎる」「不正な文字を含む」といったルールに違反した場合、それぞれのエラー内容に対応する整数値(1001、1002など)をDomainExceptionのコンストラクタ第2引数に指定して例外をスローします。
try...catchブロックでこの例外を捕捉した後、$e->getCode()メソッドを呼び出しています。このメソッドは引数を取らず、スローされた例外オブジェクトに設定されているエラーコードをint型で返します。サンプルでは、この戻り値を使ってswitch文で処理を分岐させ、エラーコードに応じた具体的な対応策メッセージを表示しています。
このように、エラーメッセージの文字列内容に頼るのではなく、codeプロパティを使ってエラーの種類を機械的に識別することで、より堅牢で保守しやすいエラー処理を実装できます。なお、このコードはPHP CodeSnifferなどのツールでチェックされることを想定した、標準的なコーディング規約に準拠して記述されています。
このサンプルコードは、例外処理におけるエラーコードの正しい使い方を示しています。DomainExceptionは、ユーザー名が長すぎるなど、アプリケーションのルール(ドメイン)に違反した場合に使うのが適切です。例外をcatchした際、getMessage()で得られるメッセージは表示用であり、変更される可能性があります。一方、getCode()で取得できる整数コードはプログラムが処理を分岐するために使います。これにより、メッセージ内容の変更に影響されない安定したエラー処理を実装できます。コード内で直接数値を書くのではなく、定数として定義することで、コードの可読性と保守性が向上します。また、phpcsのようなツールでコード規約をチェックすることは、チーム開発での品質維持に繋がる重要な習慣です。