【PHP8.x】LogicException::codeプロパティの使い方
codeプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
codeプロパティは、スローされた例外の種類を識別するための、オプションの整数コードを保持するプロパティです。このプロパティは、PHPの全ての組み込み例外クラスの親となるExceptionクラスから継承されており、LogicExceptionもその機能を利用します。例外オブジェクトを生成する際、コンストラクタの第二引数に整数値を渡すことで、このプロパティに任意の値を設定できます。もしこの引数が省略された場合、codeプロパティのデフォルト値は0となります。プロパティに設定された値は、getCode()メソッドを通じて取得することが可能です。例外メッセージが人間が読むための説明であるのに対し、このcodeはプログラムがエラーの種類を機械的に判定するために使用されます。catchブロック内でコードの値に基づいて処理を分岐させるなど、より詳細で柔軟なエラーハンドリングを実装する際に役立ちます。これにより、例えば同じLogicExceptionの中でも、エラーの具体的な原因に応じて異なる復旧処理を行うといった制御が可能になります。
構文(syntax)
1<?php 2 3try { 4 // 第2引数で例外コードを指定して、LogicExceptionをスローします。 5 throw new LogicException('An error occurred in the application logic.', 101); 6} catch (LogicException $e) { 7 // getCode()メソッドを使用して、設定された例外コードを取得します。 8 echo $e->getCode(); // 101 が出力されます。 9}
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
LogicException クラスの code プロパティは、例外発生時のエラーコードを表す整数値を返します。
サンプルコード
CodeIgniterでLogicExceptionのエラーコードを扱う
1<?php 2 3declare(strict_types=1); 4 5namespace App\Services; 6 7use LogicException; 8 9/** 10 * CodeIgniterのサービス層を模倣したサンプルクラス 11 * 12 * アプリケーションのビジネスロジックにおける不正な状態を検出し、 13 * LogicExceptionを使用してエラー処理を行う例です。 14 */ 15class OrderProcessor 16{ 17 /** 18 * 注文を処理する(という想定のメソッド) 19 * 20 * 在庫が不足しているというロジック上のエラーが発生した場合に、 21 * 固有のエラーコードを付与したLogicExceptionをスローします。 22 * 23 * @param int $itemId 商品ID 24 * @param int $quantity 注文数 25 * @return bool 処理結果 26 * @throws LogicException 在庫が不足している場合 27 */ 28 public function process(int $itemId, int $quantity): bool 29 { 30 // 実際の在庫数をデータベースなどから取得する処理を模倣 31 $stock = 5; 32 33 if ($quantity > $stock) { 34 // 在庫不足はプログラムのロジック上のエラーであるためLogicExceptionを使用 35 // 第2引数にアプリケーション固有のエラーコードを設定する 36 throw new LogicException('在庫が不足しています。', 2001); 37 } 38 39 // 注文処理を続行... 40 return true; 41 } 42} 43 44 45// --- ここからが実行部分 --- 46// CodeIgniterのコントローラ内でサービスを呼び出す処理を想定しています 47 48$processor = new OrderProcessor(); 49 50try { 51 // 在庫数(5)を超える注文(10)を処理しようとして、例外を発生させる 52 echo "注文処理を開始します...\n"; 53 $processor->process(123, 10); 54 echo "注文は正常に処理されました。\n"; 55} catch (LogicException $e) { 56 // スローされた例外をキャッチする 57 echo "エラー: 注文処理に失敗しました。\n"; 58 59 // getMessage() で例外メッセージを取得 60 echo " メッセージ: " . $e->getMessage() . "\n"; 61 62 // getCode() で例外の `code` プロパティの値を取得する 63 // このコードを利用して、エラーの種類に応じた後続処理を分岐させることができる 64 echo " エラーコード: " . $e->getCode() . "\n"; 65}
このPHPサンプルコードは、LogicExceptionのcodeプロパティを利用して、プログラムの論理的なエラーに固有のコードを割り当て、それを取得する方法を解説します。CodeIgniterなどのフレームワークにおけるサービス層でのエラー処理を想定しています。
OrderProcessorクラスのprocessメソッドは、在庫が注文数より少ないという論理的に矛盾した状況で、LogicExceptionをスロー(発生)させます。LogicExceptionを生成する際、第二引数にエラーコードとして整数値 2001 を指定しています。この値が、例外オブジェクトのcodeプロパティに保存されます。
実行部分ではtry-catch構文を使い、スローされたLogicExceptionを捕捉しています。catchブロック内で、例外オブジェクト(変数$e)のgetCode()メソッドを呼び出しています。このgetCode()メソッドは引数を取らず、戻り値として、例外に設定された整数型(int)のエラーコード(この例では 2001)を返します。
このようにcodeプロパティとgetCode()メソッドを使うことで、エラーメッセージの文字列に頼ることなく、数値コードによってエラーの種類を正確に識別し、その後の処理を分岐させることが可能になります。
LogicExceptionは、プログラムの論理的な誤り、つまり開発者が修正すべきバグを示すための例外です。外部要因のエラー(例:ファイルが見つからない)とは区別して使用します。サンプルコードで使われているcodeプロパティは、getCode()メソッドで取得できる整数値のエラーコードです。これはHTTPステータスコードとは異なり、アプリケーション内でエラーの種類を識別するために独自に定義します。例外を生成する際、コンストラクタの第2引数にこのコードを指定し、指定しない場合のデフォルト値は0です。catchブロックでこのコードを判定することで、エラーの種類に応じた処理を実装できます。エラーコードは定数として管理すると、より保守しやすくなります。
PHP LogicException の code プロパティでエラーを識別する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * PHP_CodeSnifferのようなコード規約チェッカーを模したクラスです。 7 * 8 * このサンプルは、プログラムのロジックに起因するエラー(ここでは設定ファイルの欠如)が 9 * 発生した際に、エラーの種類を識別するための整数コード(code)を付与した 10 * LogicExceptionをスローする具体的な使用例を示します。 11 */ 12final class SimpleCodeStyleValidator 13{ 14 // エラーコードを定数として定義すると、コードの可読性と保守性が向上します。 15 private const int ERROR_CODE_RULESET_NOT_FOUND = 1001; 16 17 /** 18 * 指定されたルールセットに基づき、ファイルの規約チェックを実行します。 19 * 20 * @param string $filePath チェック対象のファイルパス 21 * @param string $rulesetPath 使用するルールセットのファイルパス 22 * 23 * @throws LogicException ルールセットファイルが見つからないというロジックエラーが発生した場合 24 */ 25 public function validate(string $filePath, string $rulesetPath): void 26 { 27 // 事前条件のチェック: ルールセットファイルが存在するかどうかを確認します。 28 // このようなプログラムの内部的な矛盾や、前提条件が満たされない場合に 29 // LogicException を使用するのが適切です。 30 if (file_exists($rulesetPath) === false) { 31 // 例外をスローする際、第2引数にエラーコードを指定します。 32 // これが LogicException の 'code' プロパティに設定されます。 33 throw new LogicException( 34 "ルールセットファイルが見つかりません: {$rulesetPath}", 35 self::ERROR_CODE_RULESET_NOT_FOUND 36 ); 37 } 38 39 echo "チェック成功: {$filePath} は規約に準拠しています。" . PHP_EOL; 40 // 本来はこの部分でPHPファイルの内容を解析し、規約違反をチェックします。 41 } 42} 43 44 45// --- 以下、実行デモ --- 46 47$validator = new SimpleCodeStyleValidator(); 48$targetFile = 'src/MyClass.php'; 49 50// ケース1: 意図的に存在しないルールセットファイルを指定し、例外を発生させる 51try { 52 echo "--- ケース1: 失敗する例 ---" . PHP_EOL; 53 $validator->validate($targetFile, './nonexistent-ruleset.xml'); 54} catch (LogicException $e) { 55 // catchブロックで LogicException を捕捉します。 56 echo "エラーメッセージ: " . $e->getMessage() . PHP_EOL; 57 58 // getCode() メソッドで、例外に設定された整数コードを取得できます。 59 $errorCode = $e->getCode(); 60 echo "エラーコード: " . $errorCode . PHP_EOL; 61 62 // エラーコードに応じて、後続の処理を分岐させることができます。 63 if ($errorCode === SimpleCodeStyleValidator::ERROR_CODE_RULESET_NOT_FOUND) { 64 echo '-> (コードに基づき、設定ファイルが見つからない問題だと特定しました)' . PHP_EOL; 65 } 66} 67 68echo PHP_EOL; 69 70// ケース2: 正常に処理が成功する例 71// サンプル用にダミーのルールセットファイルを作成します。 72$validRuleset = './ruleset.xml'; 73file_put_contents($validRuleset, '<ruleset />'); 74 75try { 76 echo "--- ケース2: 成功する例 ---" . PHP_EOL; 77 $validator->validate($targetFile, $validRuleset); 78} catch (LogicException $e) { 79 // こちらは例外が発生しないため、このブロックは実行されません。 80 echo "予期せぬエラーが発生しました: " . $e->getMessage() . PHP_EOL; 81} finally { 82 // 後片付けとして、作成したダミーファイルを削除します。 83 unlink($validRuleset); 84} 85
LogicExceptionクラスのcodeプロパティは、発生した例外にエラーの種類を識別するための整数値を設定するために使用されます。このプロパティは、例外オブジェクトが生成される際に値がセットされます。
サンプルコードでは、new LogicException()の第2引数に、エラーの種類を示す定数 ERROR_CODE_RULESET_NOT_FOUND (値は1001) を渡しています。これにより、生成される例外オブジェクトのcodeプロパティにこの整数値が格納されます。
例外を捕捉したcatchブロック内では、例外オブジェクトのgetCode()メソッドを呼び出すことで、この設定されたエラーコードを取得できます。このメソッドは引数なしで呼び出すことができ、戻り値として設定された整数(int)を返します。
このcodeプロパティの主な利点は、エラーメッセージという可変的な文字列に頼らずに、エラーの種類を機械的に判定できる点にあります。サンプルコードのように、取得したエラーコードを用いてif文などで処理を分岐させることで、より堅牢で保守性の高いエラーハンドリングが可能になります。
例外に付与する整数コードは、エラーの種類を機械的に識別するために使います。エラーメッセージの文字列で処理を分岐させると、将来メッセージが変更された際にプログラムが動かなくなる可能性があるため、getCode()で取得した固定の数値で判断するのが安全な実装方法です。
エラーコードは、サンプルコードのようにconstで定数として定義することが推奨されます。これにより、意味のわからない数値を直接コードに書くことを避け、可読性と保守性を高めることができます。
LogicExceptionは、プログラムの論理的な矛盾や、満たされるべき事前条件が破られた場合に使用します。例外を生成する際は、new LogicException('メッセージ', 1001)のように、第2引数に整数コードを指定してcodeプロパティに値を設定します。