JSON 関数【あまり使わないPHP関数シリーズ】
あまり使わないけど知ってたら便利なPHP関数シリーズ第一弾。
JSONを扱うPHP関数といえば、
JSONエンコード、デコードの2つですが、
その他にも便利な関数があります。
今回JSONデータは郵便番号-住所検索APIのサンプルデータを使います。
{"code":200,"data":{"pref":"\u611b\u77e5\u770c","address":"\u540d\u53e4\u5c4b\u5e02\u4e2d\u6751\u533a\u4e0a\u7c73\u91ce\u753a","city":"\u540d\u53e4\u5c4b\u5e02\u4e2d\u6751\u533a","town":"\u4e0a\u7c73\u91ce\u753a","fullAddress":"\u611b\u77e5\u770c\u540d\u53e4\u5c4b\u5e02\u4e2d\u6751\u533a\u4e0a\u7c73\u91ce\u753a"}}
json_last_error
関数 | 説明 |
json_last_error | 直近に発生したエラーを返す |
json_encodeやjson_decode後に実行すると
変換した処理の結果を返してくれます。
APIなどで使う場合はJSON_ERROR_NONEかどうかを判定すれば良いですね。
●エラーのリスト
定数 | 意味 |
JSON_ERROR_NONE | エラーは発生しませんでした |
JSON_ERROR_DEPTH | スタックの深さの最大値を超えました |
JSON_ERROR_STATE_MISMATCH | JSON の形式が無効、あるいは壊れています |
JSON_ERROR_CTRL_CHAR | 制御文字エラー。おそらくエンコーディングが違います |
JSON_ERROR_SYNTAX | 構文エラー |
JSON_ERROR_UTF8 | 正しくエンコードされていないなど、不正な形式の UTF-8 文字 |
JSON_ERROR_RECURSION | エンコード対象の値に再帰参照が含まれています |
JSON_ERROR_INF_OR_NAN | エンコード対象の値に NAN あるいは INF が含まれています。 |
JSON_ERROR_UNSUPPORTED_TYPE | エンコード不可能な型の値が渡されました |
実際はjson_last_error_msg()を使うことになるようです。
json_last_error_msg
関数 | 説明 |
json_last_error_msg | 直近の json_encode()やjson_decode() の呼び出しのエラー文字列を返す |
PHP: json_last_error_msg - Manual
CakePHPのjson_last_error_msg()を見てみるとわかりやすいかと思います。
json_last_error()を呼び出して、エラーコード一覧からエラー内容を検索します。
日本語に書き換えるとそのまま利用できますね。
<?php /** * Provides the fallback implementation of json_last_error_msg() available in PHP 5.5 and above. * @return string Error message. */ function json_last_error_msg() { static $errors = [ JSON_ERROR_NONE => '', JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON', JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded', JSON_ERROR_SYNTAX => 'Syntax error', JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded' ]; $error = json_last_error(); return array_key_exists($error, $errors) ? $errors[$error] : "Unknown error ({$error})"; }
https://api.cakephp.org/3.0/source-function-json_last_error_msg.html#126-143
サンプル
郵便番号と住所のJSONデータを受け取ったとして、
そのデータをデコードします。
試しに$api_resulの値を適当に変更してみてください。
デコード失敗し、相応のエラーが表示されるはずです。
<?php //json.php $api_result = '{"code":200,"data":{"pref":"\u611b\u77e5\u770c","address":"\u540d\u53e4\u5c4b\u5e02\u4e2d\u6751\u533a\u4e0a\u7c73\u91ce\u753a","city":"\u540d\u53e4\u5c4b\u5e02\u4e2d\u6751\u533a","town":"\u4e0a\u7c73\u91ce\u753a","fullAddress":"\u611b\u77e5\u770c\u540d\u53e4\u5c4b\u5e02\u4e2d\u6751\u533a\u4e0a\u7c73\u91ce\u753a"}}'; $data = json_decode($api_result); if (json_last_error() === JSON_ERROR_NONE) { //デコード成功 echo "Success json_decode.\n"; var_dump($data); } else { //デコード失敗 echo "Failed json_decode.\n"; echo "json_last_error: ".json_last_error() . "\n"; echo "json_last_error_msg: ".json_last_error_msg() . "\n"; }
成功(通常)時
$ php -q json.php Success decode: /home/ubuntu/workspace/test/json.php:8: class stdClass#1 (2) { public $code => int(200) public $data => class stdClass#2 (5) { public $pref => string(9) "愛知県" public $address => string(33) "名古屋市中村区上米野町" public $city => string(21) "名古屋市中村区" public $town => string(12) "上米野町" public $fullAddress => string(42) "愛知県名古屋市中村区上米野町" } }
失敗時 - ダブルクォーテーションをひとつだけ削除
$ php -q json.php Failed decode json_last_error: 4 json_last_error_msg: object value separator ',' expected
意図しない処理を継続させないためにも、
json_encode,json_decodeのあとには入れた方がいいものですね。