本文へスキップ
jsonbeautifiers
日本語
PHP 定数名とメッセージはPHPのマニュアルによります。

json_decode() returns NULL

PHPは既定では不正なJSONに対して例外を投げません。json_decodeは単にNULLを返しますが、それは入力が"null"だった場合の正当な結果でもあるため、戻り値だけでは失敗と成功を区別できません。まずやるべきは、何が起きたのかをPHPに言わせることです。

JSONを貼り付けて、壊れている箇所を正確に確認する

入力

貼り付けたものがブラウザの外に出ることはありません。 connect-src の許可リストにより、これは約束ではなくブラウザによる保証になっています。 自分で確かめる

実際の原因

どれが答えになることが多いか、その順に並べています。

  1. 01 そもそもエラーメッセージがまだ手元にない

    デコードの直後にjson_last_error_msg()を呼ぶか、JSON_THROW_ON_ERRORフラグを渡してJsonExceptionを投げさせてください。どちらもしていなければ、手探りでデバッグしていることになります。この問題に時間がかかる理由はそこにあります。

    壊れる例

    $data = json_decode($body, true);
    if ($data === null) { /* why? */ }

    動く例

    $data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
    // or
    $data = json_decode($body, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new RuntimeException(json_last_error_msg());
    }
  2. 02 ファイル先頭のUTF-8バイトオーダーマーク

    PHPでは定番の落とし穴です。file_get_contentsはBOMをそのまま返し、json_decodeはそれを拒否します。先頭3バイトがEF BB BFなら取り除いてください。

  3. 03 不正なUTF-8。JSON_ERROR_UTF8になる

    「Malformed UTF-8 characters, possibly incorrectly encoded」は、たいていデータがLatin-1のデータベースカラムから来たことを意味します。デコード前にmb_convert_encodingで変換してください。

  4. 04 JSONの前に出力された警告やnotice

    レスポンスボディより前の出力は、すべてボディの中に入り込みます。本番ではdisplay_errorsをオフにし、ログに書いてください。

  5. 05 既定の上限より深いネスト。JSON_ERROR_DEPTHになる

    json_decodeの既定の深さは512です。データが本当にそれだけ深いなら、第3引数を上げてください。

よくある質問

JSON_ERROR系の定数にはどんなものがありますか?
JSON_ERROR_NONE(0)、JSON_ERROR_DEPTH(1、スタックの最大の深さを超過)、JSON_ERROR_STATE_MISMATCH(2)、JSON_ERROR_CTRL_CHAR(3、予期しない制御文字)、JSON_ERROR_SYNTAX(4、構文エラー、不正なJSON)、JSON_ERROR_UTF8(5、不正なUTF-8文字)、さらにJSON_ERROR_RECURSION、JSON_ERROR_INF_OR_NAN、JSON_ERROR_UNSUPPORTED_TYPE、JSON_ERROR_INVALID_PROPERTY_NAME、JSON_ERROR_UTF16、JSON_ERROR_NON_BACKED_ENUMがあります。
結果としてのNULLと、失敗としてのNULLをどう区別しますか?
json_last_error() === JSON_ERROR_NONE ならデコードは成功しており、返ってきたNULLは正真正銘の値nullです。それ以外のコードであれば失敗です。

今すぐ直す

上のツールにペイロードを貼り付けるか、この用途のために作られたツールに直接進んでください。

構文エラーを見つける