Введение: зачем PHP нужен JSON?
JSON (JavaScript Object Notation) — это легковесный формат обмена данными, который стал стандартом де-факто для веб-API, конфигурационных файлов и хранения структурированной информации. Несмотря на своё происхождение из JavaScript, JSON прекрасно поддерживается во всех современных языках программирования, включая PHP.
В PHP работа с JSON реализована нативно через две ключевые функции: json_encode() (сериализация — превращение PHP-данных в JSON-строку) и json_decode() (десериализация — парсинг JSON-строки обратно в PHP-структуры). В этой статье мы подробно разберём, как эффективно использовать эти инструменты, обрабатывать ошибки и применять JSON в реальных проектах.
1. Сериализация данных: функция json_encode()
Функция json_encode() преобразует PHP-значение (массив, объект, строку, число) в строку формата JSON. Это необходимо, когда вы хотите отправить данные клиенту (например, через AJAX) или сохранить их в файл.
Базовый синтаксис и примеры
<?php
// Простой массив
$colors = ["red", "green", "blue"];
echo json_encode($colors);
// Вывод: ["red","green","blue"]
// Ассоциативный массив
$user = [
"name" => "Иван",
"age" => 30,
"is_admin" => false
];
echo json_encode($user);
// Вывод: {"name":"Иван","age":30,"is_admin":false}
?>
Полезные флаги json_encode()
Функция поддерживает второй параметр — битовую маску флагов. Рассмотрим самые полезные:
JSON_PRETTY_PRINT— форматирует вывод с отступами для читаемости.JSON_UNESCAPED_UNICODE— не экранирует кириллицу и другие Unicode-символы (иначе русские буквы превратятся в \uXXXX).JSON_NUMERIC_CHECK— преобразует строки, содержащие числа, в числовой тип.JSON_FORCE_OBJECT— принудительно превращает массив в объект даже для индексированных массивов.
<?php
$data = ["name" => "Анна", "age" => "25"];
// Без флагов
echo json_encode($data);
// {"name":"\u0410\u043d\u043d\u0430","age":"25"}
// С флагами
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
/*
{
"name": "Анна",
"age": "25"
}
*/
?>
2. Парсинг JSON: функция json_decode()
Функция json_decode() выполняет обратную операцию — превращает JSON-строку обратно в PHP-переменную. По умолчанию она возвращает объект класса stdClass, но можно попросить ассоциативный массив.
Парсинг в объект и в массив
<?php
$jsonString = '{"name":"Петр","age":28,"skills":["PHP","MySQL"]}';
// По умолчанию — объект
$obj = json_decode($jsonString);
echo $obj->name; // Петр
echo $obj->skills[0]; // PHP
// С флагом true — ассоциативный массив
$arr = json_decode($jsonString, true);
echo $arr["name"]; // Петр
echo $arr["skills"][1]; // MySQL
?>
Глубина рекурсии
Третий параметр depth ограничивает глубину вложенности. По умолчанию — 512 уровней. Это защита от атак типа "billion laughs attack":
<?php
$malicious = '{"a":{"b":{"c":"d"}}}';
$result = json_decode($malicious, false, 2); // Максимум 2 уровня
// Вернёт null, так как глубина превышена
?>
3. Обработка ошибок при работе с JSON
Одна из самых частых проблем — некорректная JSON-строка. PHP не выбрасывает исключение при ошибке парсинга, а возвращает null. Чтобы понять, что пошло не так, используйте функцию json_last_error() и json_last_error_msg().
Проверка на ошибки
<?php
$badJson = '{"name": "Ошибка, без кавычки}';
$data = json_decode($badJson);
if (json_last_error() !== JSON_ERROR_NONE) {
echo "Ошибка JSON: " . json_last_error_msg();
// Вывод: Ошибка JSON: Syntax error, malformed JSON
}
?>
Основные коды ошибок
JSON_ERROR_NONE— ошибок нет (0).JSON_ERROR_DEPTH— превышена максимальная глубина стека.JSON_ERROR_STATE_MISMATCH— некорректный JSON (несоответствие скобок).JSON_ERROR_SYNTAX— синтаксическая ошибка (самая частая).JSON_ERROR_UTF8— некорректные UTF-8 символы.
4. Практические примеры: работа с API и файлами
Давайте рассмотрим два реальных сценария, где JSON в PHP незаменим.
Пример 1: Получение данных от внешнего API
Предположим, мы получаем курсы валют через публичное API:
<?php
$url = "https://api.exchangerate-api.com/v4/latest/USD";
$response = file_get_contents($url);
if ($response === false) {
die("Ошибка соединения с API");
}
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
die("Ошибка парсинга: " . json_last_error_msg());
}
// Выводим курс евро
echo "Курс EUR: " . $data['rates']['EUR'];
?>
Пример 2: Сохранение и загрузка конфигурации
JSON идеально подходит для конфигурационных файлов:
<?php
// Сохраняем настройки
$config = [
"db_host" => "localhost",
"db_name" => "myapp",
"debug_mode" => true
];
file_