Работа с JSON в PHP: полное руководство по парсингу и сериализации
JSON (JavaScript Object Notation) — это легковесный формат обмена данными, который широко используется в веб-разработке. PHP предоставляет мощные встроенные функции для работы с JSON, позволяя легко преобразовывать данные между PHP-структурами и JSON-строками. В этой статье мы подробно разберем, как выполнять парсинг (декодирование) и сериализацию (кодирование) JSON в PHP, а также рассмотрим типичные ошибки и способы их обработки.
Что такое JSON и зачем он нужен в PHP?
JSON — это текстовый формат, основанный на синтаксисе JavaScript. Он используется для передачи структурированных данных между сервером и клиентом (например, в REST API). В PHP JSON незаменим при:
- Обмене данными с внешними API (например, погодные сервисы, платежные системы)
- Хранении конфигурационных файлов
- Сериализации данных для кэширования
- Работе с веб-сокетами и AJAX-запросами
PHP поддерживает работу с JSON начиная с версии 5.2.0. Все необходимые функции встроены в ядро — не требуется устанавливать дополнительные расширения.
Сериализация данных в JSON (json_encode)
Функция json_encode() преобразует PHP-значения (массивы, объекты, строки, числа) в JSON-строку. Рассмотрим базовый пример:
<?php
// Ассоциативный массив
$user = [
'name' => 'Иван Петров',
'age' => 28,
'email' => 'ivan@example.com',
'is_active' => true,
'hobbies' => ['программирование', 'шахматы', 'бег']
];
// Кодируем в JSON
$jsonString = json_encode($user, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
echo $jsonString;
?>
Результат выполнения:
{
"name": "Иван Петров",
"age": 28,
"email": "ivan@example.com",
"is_active": true,
"hobbies": [
"программирование",
"шахматы",
"бег"
]
}
Важные флаги json_encode
JSON_UNESCAPED_UNICODE— сохраняет кириллицу (без этого флага русские символы будут экранированы как \uXXXX)JSON_PRETTY_PRINT— форматирует вывод с отступами для читаемостиJSON_NUMERIC_CHECK— преобразует числовые строки в числаJSON_FORCE_OBJECT— принудительно создает объект, даже если передан пустой массив
Парсинг JSON в PHP (json_decode)
Функция json_decode() выполняет обратное преобразование — из JSON-строки в PHP-значение. По умолчанию она возвращает объект. Чтобы получить ассоциативный массив, передайте второй параметр true:
<?php
$jsonString = '{"name":"Иван Петров","age":28,"email":"ivan@example.com","is_active":true}';
// Декодируем в объект
$userObject = json_decode($jsonString);
echo $userObject->name; // Иван Петров
// Декодируем в ассоциативный массив
$userArray = json_decode($jsonString, true);
echo $userArray['name']; // Иван Петров
?>
Глубина вложенности
Третий параметр json_decode() — depth — ограничивает глубину рекурсии. По умолчанию она равна 512. Это защищает от атак типа "billion laughs attack":
<?php
$deepJson = '{"a":{"b":{"c":{"d":"test"}}}}';
$data = json_decode($deepJson, true, 3); // Ошибка, если глубина больше 3
?>
Обработка ошибок при работе с JSON
При парсинге некорректного JSON json_decode() возвращает null. Чтобы получить детальную информацию об ошибке, используйте json_last_error() и json_last_error_msg():
<?php
$badJson = '{"name": "Иван", age: 28}'; // Ошибка: ключ age не в кавычках
$data = json_decode($badJson, true);
if (json_last_error() !== JSON_ERROR_NONE) {
echo 'Ошибка JSON: ' . json_last_error_msg();
// Вывод: Ошибка JSON: Syntax error, malformed JSON
}
?>
Основные коды ошибок:
JSON_ERROR_NONE— ошибок нетJSON_ERROR_DEPTH— превышена максимальная глубина стекаJSON_ERROR_STATE_MISMATCH— неверная структура JSONJSON_ERROR_SYNTAX— синтаксическая ошибкаJSON_ERROR_UTF8— некорректная UTF-8 строка
Работа с объектами и классами
Вы можете сериализовать в JSON не только массивы, но и объекты пользовательских классов. Для тонкой настройки используйте интерфейс JsonSerializable:
<?php
class User implements JsonSerializable {
private $name;
private $age;
private $password; // не должен попасть в JSON
public function __construct($name, $age, $password) {
$this->name = $name;
$this->age = $age;
$this->password = $password;
}
public function jsonSerialize(): mixed {
return [
'name' => $this->name,
'age' => $this->age,
'is_adult' => $this->age >= 18
];
}
}
$user = new User('Анна', 25, 'secret123');
echo json_encode($user, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
?>
Результат:
{
"name": "Анна",
"age": 25,
"is_adult": true
}
Практический пример: работа с API
Рассмотрим типичный сценарий —