Изменения JSON в восьмой версии PHP: практические примеры

Раздел: Версии PHP -> Версии PHP

Изменения в работе с JSON в PHP 8

Ключевые нововведения PHP 8 в области JSON касаются улучшенной обработки ошибок и новых флагов для управления кодированием и декодированием. Основное эффективное решение - использование исключений JsonException с флагом JSON_THROW_ON_ERROR.

Основной подход: исключения вместо проверки кода ошибки

Начиная с PHP 7.3 появилась возможность выбрасывать исключение при ошибках JSON, но в PHP 8 этот механизм стал стандартом и рекомендуется для всех новых проектов. Это позволяет писать более чистый и предсказуемый код.


$json = '{"name": "PHP 8"}';
try {
    $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
    echo $data['name']; // PHP 8
} catch (JsonException $e) {
    echo 'Ошибка JSON: ' . $e->getMessage();
}
  

Php 8 request (особенности обработки запросов в php 8)

В данном примере при успешном декодировании выводится значение ключа. Если JSON некорректен, вместо возврата null будет выброшено исключение, что упрощает отладку.

Возможная проблема и её решение

Если не указать флаг JSON_THROW_ON_ERROR, при ошибке функция возвращает null, и разработчик может не заметить проблему. Решение - всегда использовать этот флаг в новом коде.

Как обработать ошибки JSON без исключений?

Классический подход с проверкой json_last_error() остаётся рабочим, но более громоздкий. Он может быть полезен в легаси-проектах или там, где исключения нежелательны.


$json = '{"invalid"}';
$data = json_decode($json);
if (json_last_error() !== JSON_ERROR_NONE) {
    echo 'Ошибка: ' . json_last_error_msg();
}
  

Php 8.4 windows (php 8.4 на windows)

После вызова json_decode нужно вручную проверить код ошибки. Минус - легко забыть эту проверку, что приводит к скрытым багам.

Типичная ошибка: вызов json_decode без проверки, полагаясь на строгую типизацию

Если ожидается массив, но возвращается null, код выдаст фатальную ошибку при попытке обратиться к индексу. Решение - всегда проверять результат или использовать JSON_THROW_ON_ERROR.

Как управлять кодировкой UTF-8 в JSON?

PHP 8 поддерживает флаги JSON_INVALID_UTF8_IGNORE и JSON_INVALID_UTF8_SUBSTITUTE, позволяющие контролировать поведение при некорректных байтах UTF-8.


$string = "\x80"; // некорректный байт UTF-8
echo json_encode($string, JSON_INVALID_UTF8_SUBSTITUTE);
// выведет "\ufffd" (символ замены)
  

Php 7 функции (новые функции php 7)

Флаг JSON_INVALID_UTF8_IGNORE пропускает некорректные символы, JSON_INVALID_UTF8_SUBSTITUTE заменяет их на U+FFFD. Это полезно при обработке данных из внешних источников.

Проблема: json_encode возвращает false при недопустимых байтах

Без указанных флагов кодирование завершится ошибкой. Решение - добавить соответствующий флаг или предварительно очистить входные данные.

Как ограничить глубину рекурсии при декодировании?

По умолчанию глубина вложенности ограничена 512. В PHP 8 можно изменить это значение через параметр depth.


$json = str_repeat('{"a":', 1000) . '1' . str_repeat('}', 1000);
$data = json_decode($json, true, 1000, JSON_THROW_ON_ERROR);
  

Если глубина превышает лимит, выбрасывается исключение. Это защищает от переполнения стека.

Ошибка: превышение максимальной глубины

При получении данных из ненадёжного источника можно столкнуться с искусственно глубокой структурой. Решение - установить разумный лимит глубины, например 100, и использовать исключение.

- Php v 7 (php версия 7)
- Php 8 function (функции php 8)
- Php 5 server (php 5 сервер)

Расширенные примеры работы с JSON в PHP 8

Пример 1: Декодирование с ассоциативным массивом и строгими типами

Пример

$json = '{"count": 100, "active": true}';
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR | JSON_OBJECT_AS_ARRAY);
echo gettype($data['count']); // integer

Результат: integer. Флаг JSON_OBJECT_AS_ARRAY гарантирует, что объекты будут преобразованы в массивы даже при отсутствии второго аргумента.

Пример 2: Кодирование с отступами для красивого вывода

Пример

$data = ['name' => 'PHP 8', 'version' => 8.0];
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
echo $json;

Результат:

{
    "name": "PHP 8",
    "version": 8
}

Флаг JSON_UNESCAPED_UNICODE сохраняет символы Unicode, JSON_PRETTY_PRINT форматирует вывод.

Пример 3: Обработка циклических ссылок

Пример

$obj = new stdClass();
$obj->self = $obj;
try {
    echo json_encode($obj, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    echo 'Ошибка: ' . $e->getMessage(); // Recursion detected
}

PHP 8 выбрасывает JsonException при попытке кодировать рекурсивную структуру. Ранее это вызывало фатальную ошибку.

Пример 4: Использование константы JSON_THROW_ON_ERROR в json_encode

Пример

$data = ['key' => "\xB1\x31"]; // некорректная UTF-8 последовательность
$result = @json_encode($data, JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_IGNORE);
if ($result === false) {
    // уже не нужно, исключение перехватывается выше
}
echo $result; // {"key":"?1"} (если замена, зависит от флага)

С флагом JSON_INVALID_UTF8_IGNORE некорректные байты пропускаются. Обратите внимание: @ подавляет предупреждения, но исключение всё равно выбрасывается.

Пример 5: Пользовательский обработчик через JsonSerializable

Пример

class User implements JsonSerializable {
    public function __construct(private string $name, private string $email) {}

    public function jsonSerialize(): mixed {
        return [
            'name' => $this->name,
            'email' => $this->email,
        ];
    }
}

$user = new User('Alice', 'alice@example.com');
echo json_encode($user, JSON_THROW_ON_ERROR);
// {"name":"Alice","email":"alice@example.com"}

Интерфейс JsonSerializable позволяет объекту определять собственное представление для JSON. Это особенно удобно при работе с DTO или моделями.

PHP 8: изменения в работе с JSON - comments

En
Php 8 json (php)