JSON в PHP 7.3: отделяем ошибку разбора от значения null
Разбираем JSON в PHP 7.3 через JSON_THROW_ON_ERROR и отдельно проверяем, подходит ли структура данных приложению.
- JSON_THROW_ON_ERRORРазбор сообщает о некорректном JSON исключением
- Полученное значениеnull может быть корректным результатом
- СтруктураПроверяем поля, типы и обязательные значения
Json_decode вернул null. В документе действительно было null или JSON не удалось разобрать? Флаг JSON_THROW_ON_ERROR помогает различить эти случаи: ошибка разбора станет исключением. После успешного разбора работа не заканчивается — нужно ещё проверить поля, типы и допустимые значения.
Разбор JSON и проверка полей
<?php
function readOptions(string $raw): array {
$value = json_decode($raw, true, 32, JSON_THROW_ON_ERROR);
if (!is_array($value) || !isset($value['limit'])
|| !is_int($value['limit']) || $value['limit'] < 1
|| $value['limit'] > 100) {
throw new InvalidArgumentException('Нужен limit от 1 до 100');
}
return ['limit' => $value['limit']];
}
try {
$options = readOptions('{"limit":20}');
echo $options['limit'];
} catch (JsonException $error) {
echo 'Повреждённый JSON';
} catch (InvalidArgumentException $error) {
echo 'Неверная структура настроек';
}Функция возвращает только поле, которое ожидает приложение. Синтаксически правильный JSON ещё не описывает пригодные настройки: строка вместо числа, отрицательный предел и отсутствие ключа требуют собственной проверки. Внешний обработчик может связать эти две категории с разными сообщениями журнала, сохранив для клиента понятный ответ. Сам исходный документ записывать в журнал без разбора опасно: он может содержать секретные параметры.
Версия PHP и ограничения разбора
Флаг появился именно в PHP 7.3, поэтому пример нельзя переносить в PHP 7.2 без изменения обработки ошибок. JsonException сообщает об ошибках JSON, а не обо всех возможных проблемах приложения. Ограничение глубины задаёт допустимую вложенность, но не заменяет предел размера тела запроса. Строки должны иметь корректную кодировку UTF-8; режим исключений не исправляет повреждённые байты автоматически.
В примере глубина равна тридцати двум уровням. Для своей структуры данных выберите подходящую глубину. Не добавляйте одновременно множество флагов для подавления ошибок кодировки: тогда часть повреждённых данных может незаметно измениться. Если преобразование необходимо, опишите его отдельно и проверяйте результат до передачи бизнес-логике. Исключение удобно обрабатывать там, где ещё известен источник документа и можно сформировать контролируемый ответ.
Как проверить результат
Передайте объект с limit: 20, строковый limit, пустой объект, null и оборванный JSON. Число двадцать должен вернуть только первый вариант. Затем проверьте слишком большую вложенность и неверный UTF-8. Ошибку разбора и ошибку структуры нужно различать, чтобы было понятно, что именно исправить во входных данных.
