Json last error: примеры (PHP)

Функция json_last_error для обработки ошибок JSON в PHP
Раздел: JSON
json_last_error: int

Основные сведения о функции json_last_error

Функция json_last_error() возвращает целочисленный код последней ошибки, которая произошла при работе с JSON. Она не принимает аргументов и вызывается после выполнения операций json_decode() или json_encode().

Назначение функции

Использование функции необходимо для отладки и обработки ошибок при преобразовании данных в формат JSON и обратно. Функция позволяет определить причину неудачной операции без прерывания выполнения скрипта.

Возвращаемые значения

Функция возвращает одну из предопределенных констант:

  • JSON_ERROR_NONE (0) - ошибки отсутствуют
  • JSON_ERROR_DEPTH (1) - превышена максимальная глубина стека
  • JSON_ERROR_STATE_MISMATCH (2) - неверный или некорректный JSON
  • JSON_ERROR_CTRL_CHAR (3) - ошибка управляющего символа
  • JSON_ERROR_SYNTAX (4) - синтаксическая ошибка
  • JSON_ERROR_UTF8 (5) - некорректные UTF-8 символы
  • JSON_ERROR_RECURSION (6) - рекурсия в кодируемом значении
  • JSON_ERROR_INF_OR_NAN (7) - значение INF или NAN
  • JSON_ERROR_UNSUPPORTED_TYPE (8) - передан неподдерживаемый тип
  • JSON_ERROR_INVALID_PROPERTY_NAME (9) - недопустимое имя свойства
  • JSON_ERROR_UTF16 (10) - некорректные UTF-16 символы

Базовые примеры использования

Пример 1: Обработка успешного декодирования
$json = '{"name": "Иван", "age": 30}';
$data = json_decode($json);
$error = json_last_error();

echo 'Код ошибки: ' . $error . '\n';
echo 'Константа ошибки: ' . json_last_error_msg() . '\n';
if ($error === JSON_ERROR_NONE) {
    echo 'Декодирование прошло успешно';
}
Код ошибки: 0
Константа ошибки: No error
Декодирование прошло успешно
Пример 2: Синтаксическая ошибка в JSON
$json = '{"name": "Иван", "age": 30,}';
$data = json_decode($json);
$error = json_last_error();

echo 'Код ошибки: ' . $error . '\n';
echo 'Описание: ' . json_last_error_msg() . '\n';
if ($error === JSON_ERROR_SYNTAX) {
    echo 'Обнаружена синтаксическая ошибка';
}
Код ошибки: 4
Описание: Syntax error
Обнаружена синтаксическая ошибка
Пример 3: Ошибка кодирования специальных значений
$data = ['value' => INF];
$json = json_encode($data);
$error = json_last_error();

echo 'Результат кодирования: ' . $json . '\n';
echo 'Код ошибки: ' . $error . '\n';
echo 'Сообщение: ' . json_last_error_msg();
Результат кодирования: 
Код ошибки: 7
Сообщение: Inf and NaN cannot be JSON encoded
Пример 4: Использование флага JSON_THROW_ON_ERROR
try {
    $json = '{"invalid": }';
    $data = json_decode($json, false, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
    echo 'Поймано исключение: ' . $e->getMessage() . '\n';
    echo 'Код ошибки через функцию: ' . json_last_error();
}
Поймано исключение: Syntax error
Код ошибки через функцию: 4

Альтернативные функции в PHP

Функция возвращает текстовое описание последней ошибки. Рекомендуется использовать совместно с json_last_error() для получения полной информации об ошибке.

Исключения JsonException

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

json_validate() (PHP 8.3+)

Функция проверяет, является ли строка допустимым JSON без фактического декодирования. Полезна для валидации данных перед обработкой.

Типичные ошибки при использовании

Ошибка 1: Проверка без вызова json_decode/json_encode
$error = json_last_error();
echo 'Код ошибки: ' . $error;
if ($error === JSON_ERROR_NONE) {
    echo 'Ошибок нет';
} else {
    echo 'Есть ошибки';
}
Код ошибки: 0
Ошибок нет

Функция возвращает последнюю ошибку, поэтому если не было операций с JSON, возвращается JSON_ERROR_NONE.

Ошибка 2: Неправильная интерпретация кодов ошибок
$json = '{"name": "Иван"}';
$data = json_decode($json);

if (json_last_error() == true) {
    echo 'Есть ошибка';
} else {
    echo 'Ошибок нет';
}
Ошибок нет

Нельзя проверять ошибку как булево значение, нужно сравнивать с конкретными константами.

Ошибка 3: Использование устаревших констант
$json = '{"name": "Иван"}';
$data = json_decode($json);

switch (json_last_error()) {
    case 0:
        echo 'Успех';
        break;
    case 4:
        echo 'Синтаксическая ошибка';
        break;
    default:
        echo 'Другая ошибка';
}
Успех

Использование числовых значений вместо констант снижает читаемость кода и может привести к ошибкам при изменении PHP.

Изменения в последних версиях PHP

PHP 7.3

Добавлен флаг JSON_THROW_ON_ERROR для функций json_decode() и json_encode(). При использовании этого флага ошибки выбрасывают исключение JsonException вместо установки кода ошибки.

PHP 8.0

Изменена сигнатура json_decode() - параметр $assoc заменен на $flags. Добавлены новые константы ошибок для улучшения диагностики.

PHP 8.3

Добавлена функция json_validate() для проверки валидности JSON строки без её декодирования. Улучшена производительность обработки JSON.

Расширенные примеры использования

Пример 1: Пользовательская функция для безопасного декодирования
Пример php
function safe_json_decode($json, $assoc = false, $depth = 512, $options = 0) {
    $data = json_decode($json, $assoc, $depth, $options);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new \RuntimeException(
            'Ошибка декодирования JSON: ' . json_last_error_msg(),
            json_last_error()
        );
    }
    
    return $data;
}

try {
    $data = safe_json_decode('{"test": "value"}');
    echo 'Успешно: ' . print_r($data, true);
} catch (\RuntimeException $e) {
    echo 'Ошибка: ' . $e->getMessage();
}
Успешно: stdClass Object
(
    [test] => value
)
Пример 2: Обработка нескольких JSON операций
Пример php
$operations = [
    '{"valid": true}',
    '{"invalid": }',
    '{"another": "valid"}'
];

foreach ($operations as $index => $json) {
    $data = json_decode($json);
    $error = json_last_error();
    
    echo "Операция {$index}: ";
    if ($error === JSON_ERROR_NONE) {
        echo "Успех\n";
    } else {
        echo "Ошибка {$error} - " . json_last_error_msg() . "\n";
    }
    
    // Сброс ошибки для следующей операции не требуется,
    // так как json_last_error() всегда возвращает последнюю ошибку
}
Операция 0: Успех
Операция 1: Ошибка 4 - Syntax error
Операция 2: Успех
Пример 3: Логирование ошибок с контекстом
Пример php
function decode_with_logging($json, $context = '') {
    $data = json_decode($json);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        $errorCode = json_last_error();
        $errorMsg = json_last_error_msg();
        
        error_log("JSON ошибка [{$errorCode}] в контексте '{$context}': {$errorMsg}");
        error_log("Проблемные данные: " . substr($json, 0, 100));
        
        return null;
    }
    
    return $data;
}

$result = decode_with_logging('{"broken": json}', 'парсинг конфигурации');
echo $result === null ? 'Ошибка записана в лог' : 'Успех';
Ошибка записана в лог
Пример 4: Обработка UTF-8 ошибок
Пример php
// Некорректные UTF-8 последовательности
$json = '{"name": "' . "\x80" . '"}'; // Невалидный UTF-8
$data = json_decode($json);

if (json_last_error() === JSON_ERROR_UTF8) {
    // Попытка очистки UTF-8
    $cleaned = mb_convert_encoding($json, 'UTF-8', 'UTF-8');
    $data = json_decode($cleaned);
    
    if (json_last_error() === JSON_ERROR_NONE) {
        echo 'Данные восстановлены после очистки UTF-8';
    }
} else if (json_last_error() === JSON_ERROR_NONE) {
    echo 'Декодирование прошло успешно';
} else {
    echo 'Другая ошибка: ' . json_last_error_msg();
}
Данные восстановлены после очистки UTF-8
Пример 5: Интеграция с PSR-3 логгером
Пример php
class JsonParser {
    private $logger;
    
    public function __construct($logger) {
        $this->logger = $logger;
    }
    
    public function parse($json, $context = []) {
        $data = json_decode($json);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->logger->error('JSON parsing failed', [
                'error_code' => json_last_error(),
                'error_message' => json_last_error_msg(),
                'json_sample' => substr($json, 0, 50),
                'context' => $context
            ]);
            
            return null;
        }
        
        return $data;
    }
}

// Пример использования с Psr\Log\LoggerInterface
$parser = new JsonParser($logger);
$result = $parser->parse('{"test": "value"}', ['source' => 'api']);

Аналоги в других языках программирования

Json last error в Python

В Python используется модуль json с обработкой исключений:

import json

try:
    data = json.loads('{"invalid": }')
except json.JSONDecodeError as e:
    print(f'Ошибка: {e.msg}')
    print(f'Позиция: {e.pos}')
Ошибка: Expecting property name enclosed in double quotes
Позиция: 11

Json last error в Javascript

В JavaScript используется конструкция try-catch:

try {
    const data = JSON.parse('{"invalid": }');
} catch (error) {
    console.log(`Ошибка: ${error.message}`);
}
Ошибка: Unexpected token } in JSON at position 12

Json last error в MySQL

MySQL предоставляет функцию JSON_VALID() для проверки JSON:

SELECT JSON_VALID('{"invalid": }') as is_valid;
is_valid: 0
Go

В Go пакет encoding/json возвращает ошибку как второе значение:

import "encoding/json"

var data map[string]interface{}
err := json.Unmarshal([]byte(`{"invalid": }`), &data)
if err != nil {
    fmt.Printf("Ошибка: %v", err)
}
Ошибка: invalid character '}' looking for beginning of object key string

PHP json_last_error function comments

En
Json last error Returns the last error occurred