【PHP8.x】InvalidArgumentException::codeプロパティの使い方
codeプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『codeプロパティは、例外が発生した際の詳細な理由を示す整数値(例外コード)を保持するプロパティです。このプロパティは、InvalidArgumentExceptionクラスが継承しているPHPの基底例外クラスであるExceptionクラスで定義されています。InvalidArgumentExceptionは、メソッドや関数に渡された引数が期待される型や値と一致しない場合にスローされる例外ですが、codeプロパティを利用することで、その不正の内容をより具体的に区別できます。例えば、引数の値が範囲外である場合はコード1、形式が不正である場合はコード2といったように、開発者が任意の整数値を割り当てることが可能です。この値は、例外インスタンスを生成する際のコンストラクタの第二引数で設定し、指定しない場合は0となります。catchブロックで例外を捕捉した際には、getCode()メソッドを呼び出すことでこの値を取得でき、コードの値に応じた分岐処理を行うなど、より詳細なエラーハンドリングを実現するために役立ちます。
構文(syntax)
1<?php 2 3try { 4 // 第2引数で例外コードを指定して、InvalidArgumentExceptionをスローします。 5 throw new InvalidArgumentException("引数の値が不正です。", 400); 6} catch (InvalidArgumentException $e) { 7 // getCode()メソッドで、設定した例外コードを取得します。 8 $exceptionCode = $e->getCode(); 9 echo $exceptionCode; // 400 が出力されます。 10}
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
このプロパティは、例外が発生した原因を示す整数コードを返します。
サンプルコード
PHPでInvalidArgumentExceptionのコードを扱う
1<?php 2 3declare(strict_types=1); 4 5/** 6 * CodeIgniter のコントローラーを模した、ユーザーデータを扱うクラス 7 * 8 * このクラスは、引数のバリデーション(検証)に InvalidArgumentException を使用する例を示します。 9 */ 10final class UserController 11{ 12 /** 13 * ユーザーIDを検証し、問題がなければユーザー情報を返すメソッド 14 * 15 * CodeIgniterのコントローラーメソッドのように、外部からの入力を受け取ります。 16 * 引数が不正な場合、エラーの種類を示す `code` を持つ InvalidArgumentException をスローします。 17 * 18 * @param mixed $id 検証するユーザーID 19 * @return array<string, mixed> ユーザー情報 20 * @throws InvalidArgumentException 21 */ 22 public function findUserById(mixed $id): array 23 { 24 // IDが整数でない場合、例外をスロー (エラーコード: 1001) 25 if (!is_int($id)) { 26 throw new InvalidArgumentException( 27 'User ID must be an integer.', // エラーメッセージ 28 1001 // エラーコード 29 ); 30 } 31 32 // IDが正の数でない場合、例外をスロー (エラーコード: 1002) 33 if ($id <= 0) { 34 throw new InvalidArgumentException( 35 'User ID must be a positive integer.', // エラーメッセージ 36 1002 // エラーコード 37 ); 38 } 39 40 // 実際のアプリケーションではここでデータベースからユーザーを取得します。 41 // このサンプルでは、検証が成功したことを示すダミーデータを返します。 42 return [ 43 'id' => $id, 44 'name' => 'Taro Yamada' 45 ]; 46 } 47} 48 49// --- 以下はコントローラーを呼び出し、例外を処理する実行コード --- 50 51$controller = new UserController(); 52 53// さまざまなパターンの入力値を配列で用意 54$testCases = [1, '2', 0, -5]; 55 56foreach ($testCases as $case) { 57 echo 'Input ID: ' . var_export($case, true) . PHP_EOL; 58 try { 59 // コントローラーのメソッドを実行 60 $user = $controller->findUserById($case); 61 echo ' Success: Found user ' . $user['name'] . ' (ID: ' . $user['id'] . ')' . PHP_EOL; 62 } catch (InvalidArgumentException $e) { 63 // InvalidArgumentException がスローされた場合、ここでキャッチします 64 echo ' Error: ' . $e->getMessage() . PHP_EOL; 65 66 // Exceptionオブジェクトの getCode() メソッドを呼び出し、 67 // `code` プロパティ(整数値)を取得して表示します。 68 // これにより、エラーの種類をプログラムで判別できます。 69 $errorCode = $e->getCode(); 70 echo ' Exception Code: ' . $errorCode . PHP_EOL; 71 } 72 echo '-----------------------------' . PHP_EOL; 73}
このPHPサンプルコードは、例外処理においてエラーの種類を数値で識別するために、InvalidArgumentExceptionクラスのcodeプロパティを利用する方法を示しています。
CodeIgniterのようなフレームワークで使われるコントローラーを模したUserControllerクラスには、ユーザーIDを検証するfindUserByIdメソッドが定義されています。このメソッドは、引数の値が不正な場合に、意図的にInvalidArgumentExceptionをスロー(発生)させます。例外を生成する際、コンストラクタの第2引数に整数でエラーコードを指定すると、その値がcodeプロパティに格納されます。サンプルでは、IDが整数でない場合に1001、正の数でない場合に1002というように、エラーの種類に応じて異なるコードを設定しています。
実行部分ではtry...catch構文を使い、この例外を捕捉します。catchブロック内では、ExceptionオブジェクトのgetCode()メソッドを呼び出しています。このメソッドは引数を取らず、codeプロパティに格納されている整数値(エラーコード)を戻り値として返します。このエラーコードを利用することで、エラーメッセージの文字列に頼ることなく、プログラムでエラーの種類を正確に判別し、その後の処理を分岐させることが可能になります。
このサンプルコードは、引数が不正な場合に発生する InvalidArgumentException の code プロパティの活用例です。throw new InvalidArgumentException() の第二引数に指定した整数がエラーコードとなり、catch ブロック内で $e->getCode() を使って取得できます。エラーメッセージは主に人間が読むためのものですが、このエラーコードはプログラムがエラーの種類を正確に識別するために使われます。CodeIgniterのようなフレームワークでは、このコードを元に switch 文などで処理を分岐させ、エラーの種類に応じた適切なレスポンスを返すといった実装が可能です。エラーコードは、チーム内で意味を共有する規約として定義しておくと、より堅牢なシステム開発に繋がります。
PHPの命名規則バリデーターを実装する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * PHP_CodeSnifferのように、シンプルなコーディング規約をチェックするクラス。 7 * この例では、変数名がスネークケース形式(例: my_variable)であるかを検証します。 8 */ 9class SimpleNamingValidator 10{ 11 // 検証エラーの種類を示すエラーコードを定数として定義 12 public const E_EMPTY_STRING = 1; 13 public const E_NOT_SNAKE_CASE = 2; 14 15 /** 16 * 指定された文字列がスネークケース形式であるかを検証します。 17 * 18 * @param string $variableName 検証する変数名 19 * @throws InvalidArgumentException 引数が規約に違反した場合にスローされます 20 */ 21 public function validateSnakeCase(string $variableName): void 22 { 23 // 引数が空文字列の場合、エラーコード E_EMPTY_STRING を持つ例外をスロー 24 if ($variableName === '') { 25 throw new InvalidArgumentException( 26 '検証する文字列を空にすることはできません。', 27 self::E_EMPTY_STRING 28 ); 29 } 30 31 // 正規表現を使い、スネークケース形式でない場合、 32 // エラーコード E_NOT_SNAKE_CASE を持つ例外をスロー 33 if (!preg_match('/^[a-z0-9]+(_[a-z0-9]+)*$/', $variableName)) { 34 throw new InvalidArgumentException( 35 "変数名 '{$variableName}' はスネークケース形式ではありません。", 36 self::E_NOT_SNAKE_CASE 37 ); 38 } 39 } 40} 41 42// バリデーターのインスタンスを作成 43$validator = new SimpleNamingValidator(); 44$testCases = [ 45 'valid_variable_name', // 成功するケース 46 'invalidVariableName', // 失敗するケース (キャメルケース) 47 '', // 失敗するケース (空文字列) 48]; 49 50echo '変数名の検証を開始します...' . PHP_EOL; 51 52foreach ($testCases as $name) { 53 try { 54 // バリデーションを実行 55 $validator->validateSnakeCase($name); 56 echo "[OK] : '{$name}' は有効です。" . PHP_EOL; 57 } catch (InvalidArgumentException $e) { 58 // 例外が発生した場合、その内容を捕捉 59 // getCode() メソッドで例外に設定された整数コードを取得し、処理を分岐 60 $errorCode = $e->getCode(); 61 $message = $e->getMessage(); 62 63 echo "[エラー] : コード({$errorCode}) - {$message}" . PHP_EOL; 64 } 65} 66 67?>
このサンプルコードは、例外 InvalidArgumentException に設定されたエラーコードを取得し、利用する方法を示しています。InvalidArgumentException は、関数の引数として不正な値が渡されたことを示すために使用される、PHPに組み込まれた例外クラスです。
このコードは、PHP_CodeSnifferのような静的解析ツールを模して、変数名がスネークケース形式であるかを検証します。検証に失敗した場合、エラーメッセージだけでなく、エラーの種類を区別するための整数コードを例外に設定します。具体的には、throw new InvalidArgumentException() の第2引数に、エラーの種類を示す定数(E_EMPTY_STRING または E_NOT_SNAKE_CASE)を渡すことでコードを設定しています。
try...catch ブロックで例外を捕捉した後、$e->getCode() メソッドを呼び出すことで、この設定されたエラーコードを取得できます。getCode() メソッドは引数を取らず、例外に設定された整数(int)を戻り値として返します。このエラーコードを利用することで、なぜ処理が失敗したのか(空文字列だったのか、命名規則違反だったのか)をプログラムで正確に判断し、コードに応じた処理を分岐させることが可能になります。
このサンプルコードは、例外処理におけるエラーコードの活用方法を示しています。例外を発生させる際、エラーメッセージだけでなく、第2引数に整数でエラーコードを指定できます。このコードのように、エラーの種類ごとに定数を定義し、それをコードとして設定することで、catchブロック内でエラーの原因を機械的に判別できます。単にgetMessage()でメッセージを取得するだけでなく、getCode()で取得したコード値に応じて処理を分岐させることが可能になり、より柔軟で信頼性の高いエラーハンドリングが実現します。1や2のような数値を直接書かず、self::E_NOT_SNAKE_CASEのように意味のある名前の定数を使うことは、コードの可読性と保守性を高めるための重要な手法です。