5

Самый быстрый способ проверить, является ли строка JSON в PHP?

10

Требуется действительно очень быстрый метод проверки, является ли строка валидным JSON. Я чувствую, что это не самый эффективный способ:

function isJson($string) {
    return ((is_string($string) &&
            (is_object(json_decode($string)) ||
            is_array(json_decode($string))))) ? true : false;
}

Есть ли среди вас любители производительности, которые могли бы улучшить этот метод?

5 ответ(ов)

2

Ответ на вопрос

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

// декодируем JSON данные
// устанавливаем второй параметр в TRUE для выхода в виде ассоциативного массива.
$result = json_decode($json);

if (json_last_error() === JSON_ERROR_NONE) {
    // JSON корректен
}

// ЛИБО это эквивалентно

if (json_last_error() === 0) {
    // JSON корректен
}

Обратите внимание, что json_last_error поддерживается только в PHP >= 5.3.0.

Полная программа для проверки точной ОШИБКИ

Всегда полезно знать точную ошибку в процессе разработки. Вот полная программа для проверки точной ошибки на основе документации PHP.

function json_validate($string)
{
    // декодируем JSON данные
    $result = json_decode($string);

    // проверяем возможные ошибки JSON
    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            $error = ''; // JSON корректен // Ошибок не произошло
            break;
        case JSON_ERROR_DEPTH:
            $error = 'Превышена максимально допустимая глубина вложенности.';
            break;
        case JSON_ERROR_STATE_MISMATCH:
            $error = 'Неверный или испорченный JSON.';
            break;
        case JSON_ERROR_CTRL_CHAR:
            $error = 'Ошибка управляющего символа, возможно неправильная кодировка.';
            break;
        case JSON_ERROR_SYNTAX:
            $error = 'Синтаксическая ошибка, испорченный JSON.';
            break;
        // PHP >= 5.3.3
        case JSON_ERROR_UTF8:
            $error = 'Некорректные символы UTF-8, возможно неверная кодировка.';
            break;
        // PHP >= 5.5.0
        case JSON_ERROR_RECURSION:
            $error = 'Одна или несколько рекурсивных ссылок в значении для кодирования.';
            break;
        // PHP >= 5.5.0
        case JSON_ERROR_INF_OR_NAN:
            $error = 'Одно или несколько значений NAN или INF в значении для кодирования.';
            break;
        case JSON_ERROR_UNSUPPORTED_TYPE:
            $error = 'Передано значение типа, которое нельзя закодировать.';
            break;
        default:
            $error = 'Произошла неизвестная ошибка JSON.';
            break;
    }

    if ($error !== '') {
        // выбросить исключение или завершить выполнение // или что-либо другое :)
        exit($error);
    }

    // всё в порядке
    return $result;
}

Тестирование с допустимым JSON ВХОДОМ

$json = '[{"user_id":13,"username":"stack"},{"user_id":14,"username":"over"}]';
$output = json_validate($json);
print_r($output);

Допустимый ВЫХОД

Array
(
    [0] => stdClass Object
        (
            [user_id] => 13
            [username] => stack
        )

    [1] => stdClass Object
        (
            [user_id] => 14
            [username] => over
        )
)

Тестирование с недопустимым JSON

$json = '{background-color:yellow;color:#000;padding:10px;width:650px;}';
$output = json_validate($json);
print_r($output);

Недопустимый ВЫХОД

Синтаксическая ошибка, испорченный JSON.

Дополнительная заметка для (PHP >= 5.2 && PHP < 5.3.0)

Поскольку json_last_error не поддерживается в PHP 5.2, вы можете проверить, возвращает ли кодирование или декодирование булево значение FALSE. Вот пример:

// декодируем JSON данные
$result = json_decode($json);
if ($result === FALSE) {
    // JSON недопустим
}
1

Все, что вам на самом деле нужно сделать, это следующее...

if (is_object(json_decode($MyJSONArray))) 
{ 
    ... сделать что-то ...
}

Этот запрос даже не требует отдельной функции. Просто оберните is_object вокруг json_decode и двигайтесь дальше. Похоже, многие слишком глубоко обдумывают это решение.

0

Чтобы проверить, представляет ли ваша строка JSON-массив или JSON-объект, вы можете использовать следующую функцию:

function isJson($str) {
    $json = json_decode($str);
    return $json && $str != $json;
}

Эта функция вернет true, если строка является JSON-массивом или объектом, и false — в остальных случаях. Обратите внимание, что она отвергает строки, которые представляют только число, строку или логическое значение, хотя такие строки технически являются корректным JSON.

Вот примеры использования:

var_dump(isJson('{"a":5}')); // bool(true) - это объект
var_dump(isJson('[1,2,3]')); // bool(true) - это массив
var_dump(isJson('1')); // bool(false) - это просто число
var_dump(isJson('1.5')); // bool(false) - это тоже просто число
var_dump(isJson('true')); // bool(false) - это только логическое значение
var_dump(isJson('false')); // bool(false) - это тоже только логическое значение
var_dump(isJson('null')); // bool(false) - это просто null
var_dump(isJson('hello')); // bool(false) - это обычная строка
var_dump(isJson('')); // bool(false) - это пустая строка

Это самый короткий способ, который я смог придумать для выполнения этой задачи.

0

В версии PHP 8.3 была добавлена нативная функция json_validate(), которая позволяет легко проверять корректность JSON-строк. Вот её сигнатура:

json_validate(string $json, int $depth = 512, int $flags = 0): bool

Документацию можно найти здесь.

Если вы используете версии PHP ниже 8.3, то можно создать функцию, которая обеспечит аналогичное поведение проверки корректности JSON. Вот пример такой функции:

function is_json($string) {
  return is_numeric($string)
    || in_array($string, ['null', 'true', 'false'])
    || (is_bool($string) && $string)
    || (
      !empty($string) 
      && is_string($string) 
      && is_array(json_decode($string, true)) 
      && json_last_error() === JSON_ERROR_NONE
    );
}

Также, иногда может быть полезно проверить, содержит ли JSON-объект данные, то есть является ли он объектом или массивом. Для этого можно воспользоваться следующей функцией:

function has_json_data($string) {
  return !empty($string) 
    && is_string($string) 
    && is_array($array = json_decode($string, true)) 
    && !empty($array) 
    && json_last_error() === JSON_ERROR_NONE;
}

Обе функции помогут вам проверять корректность JSON в версиях PHP ниже 8.3.

0

Функция is_json($str) проверяет, является ли переданная строка JSON. Однако, как упомянуто в документации PHP к функции json_decode(), она вернёт null, если входная строка содержит неверное кодирование. В результате, текущая реализация функции может дать ложный результат, если строка не является корректным JSON из-за проблем с кодировкой.

Чтобы корректно проверять на валидность JSON, стоит использовать функцию json_last_error(), которая позволяет определить, возникла ли ошибка при декодировании. Вот так можно переписать вашу функцию:

function is_json($str) {
    json_decode($str);
    return (json_last_error() === JSON_ERROR_NONE);
}

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь