JSON кажется простым форматом, пока не приходит ответ от чужого API. Лишняя запятая, комментарий, одинарные кавычки или NaN — и json_decode() молча возвращает null. В итоге ошибка всплывает позже, в другом месте.
Включайте исключения
С PHP 7.3 у json_decode() есть флаг JSON_THROW_ON_ERROR. Он превращает ошибку разбора в исключение, которое невозможно случайно проигнорировать.
use JsonException;
try {
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
throw new RuntimeException('Некорректный JSON: ' . $e->getMessage());
}
Без флага проверка выглядит так: json_last_error() !== JSON_ERROR_NONE. Это работает, но легко забыть, особенно если null — допустимое значение.
Ассоциативный массив или объект
Второй аргумент true возвращает массивы вместо объектов. Для шаблонов и foreach удобнее массивы, для строгой типизации — объекты. Главное, не смешивать оба подхода в одном проекте без причины.
$object = json_decode($json, false, 512, JSON_THROW_ON_ERROR);
$array = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
Глубина и большие числа
Третий аргумент ограничивает глубину вложенности. Значение по умолчанию — 512, для обычных API этого достаточно. Слишком большое число может привести к переполнению стека на вредоносном JSON.
Числа в JSON превращаются в float или int. Идентификаторы длиннее 15–16 цифр теряют точность — храните их строками. Для денег используйте целые копейки или строки, а не float.
Кодирование ответа
При сборке JSON включайте читаемые флаги:
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
JSON_UNESCAPED_UNICODE оставляет кириллицу как есть, JSON_UNESCAPED_SLASHES не экранирует ссылки. Для отладки полезен JSON_PRETTY_PRINT, но в API он увеличивает размер ответа.
Типичные ошибки
- Комментарии. В JSON их нет:
//и/* */недопустимы. - Одинарные кавычки. Ключи и строки — только в двойных.
- Запятая перед закрывающей скобкой. Самый частый источник ошибки «Unexpected end of JSON input».
undefined,NaN,Infinity. В JSON допустим толькоnull.- BOM в начале файла. Некоторые редакторы добавляют невидимый символ, и парсер падает на первом байте.
Проверка перед отправкой
Если JSON собирается вручную или приходит из формы, проверьте его до сохранения. JSON-форматтер показывает номер строки и символа, где произошла ошибка, — это быстрее, чем искать запятую глазами.
Коротко
- всегда используйте
JSON_THROW_ON_ERROR; - не храните деньги и длинные ID в числах;
- проверяйте глубину и размер входных данных;
- для ответа API включайте
JSON_UNESCAPED_UNICODE; - ошибку JSON показывайте с позицией, а не общим «не удалось».