Глиф Учебники

json_encode и json_decode: работа с JSON

Справочник · PHP · 2 минуты чтения

JSON — текстовый формат для обмена данными между программами: в нём сайт отдаёт данные JavaScript на странице и мобильным приложениям. В PHP строку JSON делает json_encode, а читает json_decode:

PHP
<?php
$user = ['name' => 'Анна', 'age' => 25, 'langs' => ['php', 'sql']];
echo json_encode($user) . "\n";
echo json_encode($user, JSON_UNESCAPED_UNICODE) . "\n";
Вывод
{"name":"\u0410\u043d\u043d\u0430","age":25,"langs":["php","sql"]}
{"name":"Анна","age":25,"langs":["php","sql"]}

json_encode превращает массив или объект PHP в строку JSON. По умолчанию русские буквы записываются кодами вида \u0410 (это «А») — это правильный JSON, но читать его неудобно. Флаг JSON_UNESCAPED_UNICODE оставляет буквы как есть. Ещё полезны:

Флаги складываются через |:

PHP
<?php
$user = ['name' => 'Анна', 'langs' => ['php', 'sql']];
echo json_encode($user, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";
Вывод
{
    "name": "Анна",
    "langs": [
        "php",
        "sql"
    ]
}

Список с ключами 0, 1, 2… становится массивом JSON […], а массив со строковыми ключами — объектом {…}.

Из JSON в PHP

PHP
<?php
$json = '{"title": "Новости", "count": 3, "tags": ["минск", "погода"]}';
$data = json_decode($json, true);
echo $data['title'] . "\n";
echo ($data['count'] + 1) . "\n";
echo implode(', ', $data['tags']) . "\n";
Вывод
Новости
4
минск, погода

Второй аргумент true — получить ассоциативный массив. Без него json_decode вернёт объект, и к полям обращаются через стрелку: $data->title.

Ошибки разбора

Если строка — не JSON, json_decode вернёт null. Но null бывает и правильным значением ('null'), поэтому надёжнее включить исключения:

PHP
<?php
$input = '{"title": "без закрывающей скобки"';
try {
    $data = json_decode($input, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    echo 'Неверный JSON: ' . $e->getMessage() . "\n";
}

Третий аргумент 512 — допустимая глубина вложенности (значение по умолчанию; его приходится указывать, чтобы дойти до четвёртого аргумента с флагами). Без исключений причину последней ошибки показывает json_last_error_msg(). В PHP 8.3 появилась функция json_validate, которая только проверяет строку.

JSON в ответе сайта (API)

API — адреса сайта, которые отвечают не страницей для человека, а данными для программ:

PHP
<?php
$result = ['ok' => true, 'items' => [['id' => 1, 'title' => 'Хлеб']]];
header('Content-Type: application/json; charset=utf-8');
echo json_encode($result, JSON_UNESCAPED_UNICODE);

Заголовок Content-Type сообщает браузеру или программе, что пришёл JSON. Тело запроса с JSON (так его отправляет JavaScript через fetch) в $_POST не попадает — его читают целиком:

PHP
<?php
$body = json_decode(file_get_contents('php://input'), true);

Подводные камни