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"
}
Четвёртый параметр принимает флаги. JSON_OBJECT_AS_ARRAY тоже даёт массивы, но только пока второй аргумент равен null (его значение по умолчанию): json_decode($json, flags: JSON_OBJECT_AS_ARRAY) возвращает массивы, а json_decode($json, false, 512, JSON_OBJECT_AS_ARRAY) по-прежнему возвращает объекты.
Обход вложенного JSON
Ответы API обычно это список объектов внутри объекта. Декодируйте один раз, затем обходите через 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() возвращает null для неверного JSON, но null это ещё и правильный результат для JSON-текста null, поэтому один null не говорит, был ли сбой. json_last_error_msg() сообщает причину последнего вызова. Более чистый способ это JSON_THROW_ON_ERROR, который выбрасывает JsonException:
Вывод:
NULL
Syntax error
NULL
No error
Invalid JSON: Syntax error
Третий аргумент, 512, это максимальная глубина вложенности (по умолчанию). С именованными аргументами его можно пропустить: json_decode($json, true, flags: JSON_THROW_ON_ERROR).
Проверка корректности JSON через json_validate()
В 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: проверка заранее разбирает строку дважды.
Чтение JSON-файла
Прочитайте файл через file_get_contents() и декодируйте строку. Этот блок сначала записывает settings.json, чтобы было что читать:
Вывод:
Theme: dark
Plugins: 2
{
"theme": "dark",
"fontSize": 16,
"plugins": [
"git",
"lint"
]
}
Почему json_decode возвращает null: частые причины
JSON строже, чем синтаксис JavaScript и массивов PHP. Каждая строка ниже выглядит разумно, и каждая возвращает null. Запустите, чтобы увидеть причину для каждой, затем исправьте одну и запустите снова:
Вывод:
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"
Метка порядка байтов (BOM) невидима в большинстве редакторов, и это классическая причина того, что JSON-файл "выглядит нормально", но не декодируется. Уберите её через $text = preg_replace('/^\xEF\xBB\xBF/', '', $text); перед декодированием.
Часто задаваемые вопросы
Как преобразовать JSON в массив в PHP?
Передайте 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 с причиной.
Как проверить, является ли строка корректным JSON в PHP?
Начиная с PHP 8.3 json_validate($string) возвращает true или false, не строя декодированное значение. В более старых версиях декодируйте строку и проверьте json_last_error() === JSON_ERROR_NONE.
Как прочитать JSON-файл в PHP?
Прочитайте файл, потом декодируйте: $data = json_decode(file_get_contents('data.json'), true, flags: JSON_THROW_ON_ERROR);. file_get_contents() возвращает false, если файла нет, поэтому сначала проверьте это.
Как обратиться к ключу JSON с дефисом в PHP?
Декодируйте в массив и используйте $data['first-name'], а с объектами используйте фигурные скобки: $obj->{'first-name'}. Тот же синтаксис со скобками работает для ключей-чисел, например $obj->{'0'}.