Menu

PHPのjson_decode():JSONを連想配列やオブジェクトに変換

json_decode($json, true)はJSONの文字列をPHPの連想配列に変換し、trueを付けなければstdClassのオブジェクトになります。ネストした値、JSON_THROW_ON_ERRORでのエラー処理、json_validate()、json_decodeがnullを返す理由を学びます。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

json_decode($json, true)は、JSONの文字列をPHPの値に変換し、すべてのJSONオブジェクトを連想配列にします。trueを省くと、JSONオブジェクトは代わりに->で読むstdClassのオブジェクトになります。不正なJSONはnullになります。

出力:

Ada
js
Ada
php
Array
(
    [name] => Ada
    [age] => 36
    [langs] => Array
        (
            [0] => php
            [1] => js
        )

    [admin] => 1
)

JSON配列は、どちらのモードを選んでも常にPHPのリストになります。逆の方向、つまりPHPからJSONへの変換はjson_encode()です。

連想配列かオブジェクトか:trueとfalse

どちらのモードも同じデータを持つので、コードが読みやすくなるほうを選びます。配列はすべての配列関数(array_column、array_map、isset($data['key']))と一緒に使えるので、ほとんどのコードはtrueを渡します。オブジェクトでは、ハイフンや数字を含むキーのように、プロパティ名として有効でないキーに波括弧の構文が必要です。

出力:

Ada zero London
Ada zero London
object(stdClass)#2 (1) {
  ["city"]=>
  string(6) "London"
}

4つ目の引数はフラグを受け取ります。JSON_OBJECT_AS_ARRAYでも配列が得られますが、2つ目の引数がnull(デフォルト)の間だけです。json_decode($json, flags: JSON_OBJECT_AS_ARRAY)は配列を返しますが、json_decode($json, false, 512, JSON_OBJECT_AS_ARRAY)はやはりオブジェクトを返します。

ネストしたJSONをループする

APIのレスポンスは、たいていオブジェクトの中のオブジェクトのリストです。1回デコードしてからforeachでたどり、欠けているかもしれないフィールドには??を使います。

出力:

#1 Ada <ada@example.com> roles: admin, editor
#2 Linus <no email> roles: none
#3 Grace <grace@example.com> roles: editor
Array
(
    [1] => Ada
    [2] => Linus
    [3] => Grace
)

不正なJSONを処理する

json_decode()は不正なJSONにnullを返しますが、nullはJSONのテキストnullに対する正しい結果でもあるので、nullだけでは失敗したかどうかわかりません。json_last_error_msg()は直前の呼び出しの理由を返します。よりすっきりした方法は、JsonExceptionを投げるJSON_THROW_ON_ERRORです。

出力:

NULL
Syntax error
NULL
No error
Invalid JSON: Syntax error

3つ目の引数512はネストの最大の深さ(デフォルト)です。名前付き引数を使えば省略できます:json_decode($json, true, flags: JSON_THROW_ON_ERROR)。

json_validate()で文字列が正しいJSONか確認する

PHP 8.3でjson_validate()が追加されました。デコードした配列を作らずにtrueかfalseを答えるので、たとえばリクエストの本文を早めに拒否する場合のように、知りたいのが正しいかどうかだけなら、デコードよりメモリを使いません。

出力:

'{"a": 1}'    valid
'[1, 2, 3]'   valid
'"text"'      valid
'{a: 1}'      invalid: Syntax error
'{\'a\': 1}'  invalid: Syntax error
''            invalid: Syntax error

どうせデータを使うのなら、json_validate()は使わずにJSON_THROW_ON_ERRORでデコードしましょう。先に検証すると文字列を2回解析することになります。

JSONファイルを読み込む

file_get_contents()でファイルを読み、文字列をデコードします。このブロックは、読むファイルがあるよう先にsettings.jsonを書き出します。

出力:

Theme: dark
Plugins: 2
{
    "theme": "dark",
    "fontSize": 16,
    "plugins": [
        "git",
        "lint"
    ]
}

json_decodeがnullを返す:よくある原因

JSONはJavaScriptやPHPの配列の構文より厳格です。下の文字列はどれももっともらしく見えますが、どれもnullを返します。実行してそれぞれの理由を確認し、1つ直してからもう一度実行してみてください。

出力:

single quotes    Syntax error
unquoted key     Syntax error
trailing comma   Syntax error
comment          Syntax error
byte order mark  Syntax error
too deep         Maximum stack depth exceeded
float(1.2345678901234567E+19)
string(20) "12345678901234567890"

バイトオーダーマークはほとんどのエディターで見えず、JSONファイルが「正しく見える」のにデコードできない定番の理由です。デコードの前に$text = preg_replace('/^\xEF\xBB\xBF/', '', $text);で取り除きましょう。

よくある質問

PHPでJSONを配列に変換するには?

2つ目の引数にtrueを渡します:json_decode('{"name":"Ada"}', true)は['name' => 'Ada']を返すので、値は$data['name']で読みます。trueがなければ、JSONオブジェクトはstdClassのオブジェクトになり、$data->nameと書きます。

json_decodeがnullを返すのはなぜですか?

JSONが不正(シングルクォート、末尾のカンマ、引用符のないキー、バイトオーダーマーク)か、深さの上限より深くネストしているか、JSONが本当にnullであるかです。json_last_error_msg()を確認するか、JSON_THROW_ON_ERRORでデコードして理由付きのJsonExceptionを得ます。

PHPで文字列が正しいJSONか確認するには?

PHP 8.3以降、json_validate($string)がデコードした値を作らずにtrueかfalseを返します。それより古いバージョンでは、デコードしてjson_last_error() === JSON_ERROR_NONEを確認します。

PHPでJSONファイルを読み込むには?

ファイルを読んでからデコードします:$data = json_decode(file_get_contents('data.json'), true, flags: JSON_THROW_ON_ERROR);。ファイルがないとfile_get_contents()はfalseを返すので、先にそれを確認しましょう。

PHPでハイフンを含むJSONのキーにアクセスするには?

配列にデコードして$data['first-name']を使うか、オブジェクトなら波括弧を使います:$obj->{'first-name'}。同じ波括弧の構文は、$obj->{'0'}のように数字のキーにも使えます。

Coddyのプログラミング言語のイラスト

Coddyでコードを学ぼう

始める