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

Четвёртый параметр принимает флаги. 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'}.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ