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'}のように数字のキーにも使えます。