Самый быстрый способ проверить, является ли строка JSON в PHP?
Требуется действительно очень быстрый метод проверки, является ли строка валидным JSON. Я чувствую, что это не самый эффективный способ:
function isJson($string) {
return ((is_string($string) &&
(is_object(json_decode($string)) ||
is_array(json_decode($string))))) ? true : false;
}
Есть ли среди вас любители производительности, которые могли бы улучшить этот метод?
5 ответ(ов)
Ответ на вопрос
Функция 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 недопустим
}
Все, что вам на самом деле нужно сделать, это следующее...
if (is_object(json_decode($MyJSONArray)))
{
... сделать что-то ...
}
Этот запрос даже не требует отдельной функции. Просто оберните is_object
вокруг json_decode
и двигайтесь дальше. Похоже, многие слишком глубоко обдумывают это решение.
Чтобы проверить, представляет ли ваша строка 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) - это пустая строка
Это самый короткий способ, который я смог придумать для выполнения этой задачи.
В версии 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.
Функция 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.
Возвращение JSON из PHP-скрипта
Ошибка "Невозможно использовать объект типа stdClass как массив"
Предпочтительный метод хранения массивов PHP: json_encode или serialize?
Как получить расширение файла в PHP?
Как преобразовать jsonString в JSONObject в Java?