【PHP8.x】JsonException::codeプロパティの使い方
codeプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
codeプロパティは、JSON処理で発生したエラーの種類を示すエラーコードを保持するプロパティです。このプロパティは、PHPの基本的な例外クラスであるExceptionクラスから継承されたもので、標準的な例外処理の規約に沿って動作します。json_encode()関数やjson_decode()関数などがJSON文字列の処理に失敗し、JsonExceptionがスローされた際に、エラーの具体的な原因を示す整数値がこのプロパティに自動的に設定されます。この値は、関数json_last_error()が返すエラーコードと同一のものです。開発者は、このcodeプロパティの値を、PHPで定義済みの一連のJSON_ERROR_*定数(例: JSON_ERROR_SYNTAX, JSON_ERROR_UTF8など)と比較することで、構文エラーや不正なUTF-8シーケンスといった、発生したエラーの詳細を正確に識別できます。通常はtry-catchブロック内で捕捉したJsonExceptionオブジェクトのgetCode()メソッドを通じてこの値を取得し、エラーの種類に応じた適切な分岐処理を実装するために利用します。
構文(syntax)
1<?php 2 3$invalidJsonString = '{"key": "value",}'; 4 5try { 6 json_decode($invalidJsonString, true, 512, JSON_THROW_ON_ERROR); 7} catch (JsonException $e) { 8 // JsonException オブジェクトから例外コードを取得します。 9 // この値は json_last_error() が返す定数に対応します。 10 $errorCode = $e->getCode(); 11 var_dump($errorCode); // 例: int(4) (JSON_ERROR_SYNTAX) 12}
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
JSONデコードまたはエンコード中に発生したエラーコードを整数で返します。
サンプルコード
PHP: JsonExceptionのcodeでJSONエラーを取得する
1<?php 2 3/** 4 * このサンプルは、CodeIgniter 4のAPIコントローラでの利用を想定した、 5 * JsonExceptionの`code`プロパティ(実際にはgetCode()メソッド経由)の 6 * 使用例を示すための、単体で動作するコードです。 7 */ 8class JsonHandlerSimulator 9{ 10 /** 11 * 不正なJSON文字列を処理し、エラーレスポンスを生成します。 12 * これは、CodeIgniterのコントローラ内のメソッドに相当します。 13 */ 14 public function processJsonRequest(): void 15 { 16 // APIリクエストで受け取った、不正な形式のJSONデータをシミュレートします。 17 // (キー "isActive" の後のカンマが構文エラーを引き起こします) 18 $invalidJsonInput = '{"userId": 1, "isActive": true,}'; 19 20 try { 21 // PHP 8では、JSON_THROW_ON_ERRORフラグを使用することが推奨されます。 22 // このフラグにより、JSONのデコードに失敗するとJsonExceptionがスローされます。 23 $data = json_decode($invalidJsonInput, true, 512, JSON_THROW_ON_ERROR); 24 25 // 成功した場合のレスポンスをJSON形式で出力します。 26 // CodeIgniterでは `$this->respond($response, 200);` のように記述します。 27 $this->sendJsonResponse([ 28 'status' => 'success', 29 'message' => 'JSONの解析に成功しました。', 30 'data' => $data, 31 ], 200); 32 33 } catch (JsonException $e) { 34 // JsonExceptionを捕捉した場合の処理です。 35 36 // $e->getCode() を使って、JSONのエラーコード(int型)を取得します。 37 // この例では構文エラーのため、JSON_ERROR_SYNTAX (値: 4) が返されます。 38 $jsonErrorCode = $e->getCode(); 39 40 // エラーレスポンスの本体を構築します。 41 $errorResponse = [ 42 'status' => 'error', 43 'message' => '無効なJSONデータが提供されました。', 44 'json_error_code' => $jsonErrorCode, // 取得したエラーコード 45 'details' => $e->getMessage(), 46 ]; 47 48 // HTTPステータス 400 (Bad Request) と共にエラーレスポンスを出力します。 49 // CodeIgniterでは `$this->fail($errorResponse, 400);` のように記述します。 50 $this->sendJsonResponse($errorResponse, 400); 51 } 52 } 53 54 /** 55 * HTTPレスポンスをシミュレートして出力します。 56 * 57 * @param array $body レスポンスのデータ 58 * @param int $statusCode HTTPステータスコード 59 */ 60 private function sendJsonResponse(array $body, int $statusCode): void 61 { 62 // コマンドライン実行でない場合は、実際のHTTPヘッダーを設定します。 63 if (PHP_SAPI !== 'cli') { 64 header('Content-Type: application/json; charset=utf-8'); 65 http_response_code($statusCode); 66 } 67 68 // レスポンスボディを整形して出力します。 69 echo json_encode($body, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . PHP_EOL; 70 } 71} 72 73// クラスのインスタンスを作成し、リクエスト処理メソッドを実行します。 74$handler = new JsonHandlerSimulator(); 75$handler->processJsonRequest();
このPHPサンプルコードは、json_decode関数でJSON文字列の解析に失敗した際に発生する JsonException から、具体的なエラーの種類を示すエラーコードを取得する方法を説明するものです。リファレンスにある code プロパティは、実際には getCode() メソッドを呼び出すことで取得します。
コードの中では、tryブロック内で JSON_THROW_ON_ERROR オプションを指定して json_decode を実行しています。このオプションにより、提供された不正な形式のJSON文字列を解析しようとすると JsonException という例外が発生します。
続く catch ブロックでこの例外を捕捉し、例外オブジェクト $e に対して getCode() メソッドを使用しています。このメソッドは引数を取らず、戻り値としてJSON解析エラーの種類を特定するための整数値(int型)を返します。サンプルコードでは、JSONの構文エラーが原因であるため、$e->getCode() は JSON_ERROR_SYNTAX に対応する 4 という整数を返します。
このように取得したエラーコードをAPIのエラーレスポンスに含めることで、どのような問題が発生したのかをAPIの利用者に具体的に伝えることができます。これは、CodeIgniterのようなフレームワークでAPIを開発する際に非常に役立つ手法です。
json_decode関数でエラーが発生した際にJsonExceptionをスローさせるには、第4引数にJSON_THROW_ON_ERRORを指定することが必須です。この指定がないと例外は発生しません。try...catch構文でJsonExceptionを捕捉した後、$e->getCode()メソッドを使うことで、JSONのエラー原因を示す番号を取得できます。この番号はHTTPステータスコードとは異なり、「構文エラー」や「深すぎる階層」といった具体的なエラーの種類を特定するためのものです。この仕組みを利用することで、APIのエラーレスポンスに詳細な情報を含めることができ、デバッグが容易になります。CodeIgniterでは、ここで得たエラー情報を$this->fail()メソッドに渡すことで、規格に沿ったエラーレスポンスを簡単に生成できます。
PHP: JsonExceptionエラーコードを取得する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * JsonExceptionのcodeプロパティの使用例を示すクラス。 7 * 8 * このコードはPHP CodeSnifferのPSR-12標準コーディング規約に準拠しています。 9 */ 10final class JsonErrorCodeChecker 11{ 12 /** 13 * 不正なJSON文字列をデコードし、発生した例外のエラーコードを表示します。 14 * 15 * json_decodeでJSON_THROW_ON_ERRORフラグを使用すると、 16 * パースエラー時にJsonExceptionがスローされます。 17 * 18 * @param string $invalidJson 不正な形式のJSON文字列 19 * 20 * @return void 21 */ 22 public function displayJsonErrorCode(string $invalidJson): void 23 { 24 try { 25 // JSON_THROW_ON_ERRORフラグを指定して、デコードエラー時に例外を発生させる 26 json_decode($invalidJson, true, 512, JSON_THROW_ON_ERROR); 27 } catch (JsonException $e) { 28 // JsonExceptionをキャッチし、エラー情報を表示する 29 echo 'JSONデコードに失敗しました。' . PHP_EOL; 30 31 // $e->codeプロパティ(またはgetCode()メソッド)でエラーコードを取得 32 // このコードはjson_last_error()が返す定数に対応します 33 $errorCode = $e->getCode(); 34 35 echo 'エラーメッセージ: ' . $e->getMessage() . PHP_EOL; 36 echo 'エラーコード: ' . $errorCode . PHP_EOL; 37 38 // エラーコードに対応する定数名を表示する 39 $this->printJsonErrorConstantName($errorCode); 40 } 41 } 42 43 /** 44 * JSONエラーコードに対応する定数名を出力します。 45 * 46 * @param int $code JsonExceptionから取得したエラーコード 47 * 48 * @return void 49 */ 50 private function printJsonErrorConstantName(int $code): void 51 { 52 $errorConstants = [ 53 JSON_ERROR_NONE => 'JSON_ERROR_NONE', 54 JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH', 55 JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH', 56 JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR', 57 JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX', 58 JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8', 59 JSON_ERROR_RECURSION => 'JSON_ERROR_RECURSION', 60 JSON_ERROR_INF_OR_NAN => 'JSON_ERROR_INF_OR_NAN', 61 JSON_ERROR_UNSUPPORTED_TYPE => 'JSON_ERROR_UNSUPPORTED_TYPE', 62 JSON_ERROR_INVALID_PROPERTY_NAME => 'JSON_ERROR_INVALID_PROPERTY_NAME', 63 JSON_ERROR_UTF16 => 'JSON_ERROR_UTF16', 64 ]; 65 66 $errorName = $errorConstants[$code] ?? '不明なエラーコード'; 67 echo '対応する定数: ' . $errorName . PHP_EOL; 68 } 69} 70 71// 不正なJSON文字列(末尾に余分なカンマがあるため構文エラーとなる) 72$invalidJsonString = '{"user": "php-user", "active": true,}'; 73 74$checker = new JsonErrorCodeChecker(); 75$checker->displayJsonErrorCode($invalidJsonString); 76
このPHPサンプルコードは、JSON文字列のデコード時に発生するエラーの詳細な原因を特定する方法を示しています。
json_decode関数に JSON_THROW_ON_ERROR オプションを指定すると、デコードに失敗した場合に JsonException という例外が発生します。このコードでは try...catch 構文を使い、この例外を意図的に捕捉しています。
catch ブロックで受け取った JsonException オブジェクト $e の code プロパティ(または getCode() メソッド)を呼び出すことで、エラーコードを整数(int)型で取得できます。このプロパティに引数はなく、戻り値としてエラーの種類を示す整数を返します。このエラーコードは、PHPにあらかじめ定義されている JSON_ERROR_SYNTAX (構文エラー) などの定数値に対応しています。
サンプルでは、末尾に余分なカンマを持つ不正なJSON文字列を displayJsonErrorCode メソッドに渡しています。これにより JsonException が発生し、code プロパティから取得したエラーコードと、それに対応する定数名 JSON_ERROR_SYNTAX がコンソールに出力されます。このように、JsonException の code を確認することで、エラーの原因に応じた適切な処理を実装できます。
json_decodeで発生するエラーを扱う際の注意点です。このコードのようにJsonExceptionを発生させるには、json_decodeの第4引数にJSON_THROW_ON_ERRORフラグを指定することが必須です。このフラグを使う場合、不正なJSON文字列が渡されると例外が発生するため、必ずtry...catchブロックで処理を囲ってください。囲まないとプログラムが停止してしまいます。catchした例外オブジェクトのgetCode()メソッド(またはcodeプロパティ)で取得できるエラーコードは、JSON_ERROR_SYNTAXのようなPHPの定義済み定数に対応する整数値です。この定数と比較することで、エラーの具体的な原因を判別できます。