PHP で JSON ファイルを読み込んでデコードに失敗しても例外ではなく null
が返りエラーになったことに気づきづらいので例外を発生させるメモ
<?php $json = "{"; $data = json_decode($json, true); var_dump($data); // => NULL
JSON ファイルを読み込んで配列にして返したい
<?php function loadFile(string $file): string { if ( !is_file($file) ) { throw new \Exception("{$file} is not a file"); } $contents = file_get_contents($file); if ( $contents === false ) { throw new \Exception("Error reading file at {$file}"); } return $contents; } function jsonDecode(string $jsonFile): array { $json = loadFile($jsonFile); // JSON のデコードに失敗しても NULL が返るのをどうにかしたい $data = json_decode($json, true); return $data; }
1. json_last_error でエラーをキャッチする
json_last_error
は直前に発生したエラーを返す
cf. PHP: json_last_error - Manual
json_last_error
で返されるエラーの種類は定数で、実際のエラーメッセージは json_last_error_msg
で取得できる
<?php function jsonDecode(string $jsonFile): array { $json = loadFile($jsonFile); $data = json_decode($json, true); // JSON decode のエラー if ( json_last_error() !== \ JSON_ERROR_NONE ) { throw new \InvalidArgumentException("Error of parsing JSON.\n" . json_last_error_msg() . ":" . json_last_error()); } return $data; } // エラーのキャッチ try { $jsonData = jsonDecode($jsonFile); } catch ( \InvalidArgumentException $e ) { // JSON decode error }
cf.
2. JSON_THROW_ON_ERROR オプションを使う (PHP > 7.3)
json_decode(string $json, ?bool $associative = null, int $depth = 512, int $flags = 0)
第4引数に JSON_THROW_ON_ERROR
を渡すとデコードのエラーがある場合に JsonException
を発生させる
JSON_THROW_ON_ERROR
エラーが起きた場合、 json_last_error() や json_last_error_msg() 関数で収集される、 グローバルなエラー状態を設定するかわりに、 JsonException をスローします。 JSON_PARTIAL_OUTPUT_ON_ERROR は JSON_THROW_ON_ERROR よりも優先します。 PHP 7.3.0 以降で使用可能です。
cf. PHP: 定義済み定数 - Manual
<?php function jsonDecode(string $jsonFile): array { $json = loadFile($jsonFile); $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR); return $data; } // エラーのキャッチ try { $jsonData = jsonDecode($jsonFile); } catch ( \JsonException $e ) { // JSON decode error }
cf.
所管
流石にもう多くのプロジェクトでは PHP v7.4 以上だと思うので JSON_THROW_ON_ERROR
オプションを使う方がエラーも独自の JsonException
なのでエラーハンドリングするのに良さそうかな〜と思いました。
おわり ₍ ᐢ. ̫ .ᐢ ₎
[参考]