現役プログラマのWordPressカスタマイズ相談

WordPress(ワードプレス)のお悩み、うまくいかなくてお困りなこと、不具合調査、新規制作依頼まで、ウェブアプリケーションエンジニアがあなたをサポートします。

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"}}

郵便番号-住所検索API


json_last_error

関数 説明
json_last_error 直近に発生したエラーを返す

PHP: json_last_error - Manual

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


CakePHPjson_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のあとには入れた方がいいものですね。