PHP 8.3: Добавлена функция json_validate
json_validate
, возвращающая true
или false
в зависимости от того, является ли заданная строка допустимой JSON-строкой.До PHP 8.3 единственным способом определить, является ли заданная строка допустимой JSON-строкой, была попытка её декодирования и проверки наличия каких-либо ошибок. Новая функция json_validate
использует тот же базовый синтаксический анализатор JSON, что и PHP, но потребляет меньше памяти и ресурсов процессора чем json_decode
, поскольку только анализирует строку, не создавая никакого декодированного значения.
Приложения, в которых предусмотрены строгие меры для предотвращения обработки недопустимых JSON-строк, могут найти новую функцию не столько полезной. Поскольку вызов json_validate
, за которым следует json_decode
, может немного увеличить время выполнения, так как JSON-строка будет анализироваться дважды. Существует большая вероятность, что входящая строка будет допустимой JSON-строкой.
Приложения, которые принимают предоставленный пользователем JSON или подключаются к удалённым JSON API-интерфейсам, могут наилучшим способом использовать новый параметр json_validate
, поскольку существует значительная вероятность обнаружения недопустимых JSON-строк.
json_validate('[1, 2, 3]'); // true
json_validate('{1, 2, 3]'); // false
Описание функции json_validate
/**
* Проверяет заданную строку на соответствие JSON.
*
* @param string $json Строка для проверки
* @param int $depth Установите максимальную глубину. Должно быть больше нуля.
* @param int $flags Битовая маска флагов.
* @return bool true если $json содержит допустимую JSON-строку, иначе false.
*/
function json_validate(string $json, int $depth = 512, int $flags = 0): bool {
}
json_validate
объявлен в глобальном пространстве имён- Ошибки валидации можно получить с помощью существующих функций
json_last_error
иjson_last_error_msg
- Смотри Принимаемые флаги
json_validate
для списка принимаемых флагов. Передача недопустимого флага вызовет исключениеError
. - Примеры использования смотри в Примеры
json_validate
Принимаемые флаги json_validate
($flags
)
Функция json_validate
принимает битовую маску флагов в качестве третьего параметра $flags
. Хотя возможно, что дополнительные флаги будут добавлены в более новых версиях PHP. На данный момент JSON_INVALID_UTF8_IGNORE
единственный допустимый флаг для параметра $flags
.
JSON_INVALID_UTF8_IGNORE
— константа PHP (начиная с PHP 7.2), которую также принимает функция json_decode
.
При передаче этого флага функциям json_decode
и json_ignore
, они игнорируют символы UTF-8 в заданной строке.
json_validate('[1, 2, 3]', flags: JSON_INVALID_UTF8_IGNORE); // true
json_validate("[\"\xc1\xc1\",\"a\"]"); // false
json_validate("[\"\xc1\xc1\",\"a\"]", flags: JSON_INVALID_UTF8_IGNORE); // true
В приведённом выше фрагменте используются именованные параметры, добавленные в PHP 8.0, и escape-последовательности шестнадцатеричных символов.
Ошибки валидации json_validate
Функция json_validate
не возвращает код ошибки валидации (например, синтаксическая ошибка, слишком большая глубина, неподдерживаемый тип и т.д.). Однако для определения ошибки валидации можно использовать существующие функции json_last_error
и json_last_error_msg
.
json_validate(""); // false
json_last_error(); // 4
json_last_error_msg(); // "Syntax error"
json_validate("null"); // true
json_last_error(); // 0
json_last_error_msg(); // "No error"
Подобно функциям
json_decode
иjson_encode
,json_validate
изменяет состояние приложения, сохраняя код ошибки последней операции, что делаетjson_validate
не чистой функцией. Хотя это не должно оказывать существенного влияния на большинство PHP-приложений, могут быть пограничные случаи, в том числе условия гонки на некоторых новых PHP раннерах, которые обслуживают несколько одновременных запросов в одном потоке.
Примеры использования
Ниже приведены некоторые примеры использования новой функции json_decode
. Они не проверяют, доступна ли функция json_validate
в работающей версии PHP. Приложениям/пакетам, которым необходимо поддерживать версии старше PHp 8.3, может потребоваться либо условное использование json_validate
, либо использование полифилла в пользовательском PHP коде.
Валидация заданной JSON-строки
json_validate($_GET['json']);
Валидация заданной JSON-строки и выдача исключения
Это имитирует флаг JSON_THROW_ON_ERROR
представленный в PHP 7.3.
if (json_validate($_GET['json']) === false) {
throw new \JsonException(json_last_error_msg(), json_last_error());
}
Замена существующей валидации JSON новой функцией json_validate
- $value = json_decode($_GET['json'], flags: JSON_THROW_ON_ERROR);
+ if (!json_validate($_GET['json'])) {
+ throw new \JsonException(json_last_error_msg(), json_last_error());
+ }
+ $value = json_decode($_GET['json']);
Полифилл
Внутренняя реализация функции json_validate()
потребляет меньше ресурсов, и это главное преимущество функции json_validate
. Можно использовать полифилл в пользовательском PHP-коде, наблюдая за ошибками накопленными в json-decode
, но это не даёт преимуществ в использовании памяти/вычислений по сравнению с фактической реализацией.
if (!function_exists('json_validate')) {
function json_validate(string $json, int $depth = 512, int $flags = 0): bool {
if ($flags !== 0 && $flags !== \JSON_INVALID_UTF8_IGNORE) {
throw new \ValueError('json_validate(): Argument #3 ($flags) must be a valid flag (allowed flags: JSON_INVALID_UTF8_IGNORE)');
}
if ($depth <= 0 ) {
throw new \ValueError('json_validate(): Argument #2 ($depth) must be greater than 0');
}
\json_decode($json, null, $depth, $flags);
return \json_last_error() === \JSON_ERROR_NONE;
}
}
Приведённый выше фрагмент должен работать в PHP 8.0 и более поздних версиях. Если заменить \ValueError
другим типом исключения, то полифилл будет совместим с PHP >= 7.3.
Влияние обратной совместимости
json_validate()
— новая функция добавленная в PHP 8.3. Существующие PHP-приложения, объявляющие функцию json_validate
в глобальном пространстве имён, столкнутся с ошибкой повторного объявления функции в PHP 8.3.
Эта функция может быть реализована в пользовательском PHP-коде, хотя она не может дать преимуществ памяти/обработке, которые даёт актуальная функция json_validate
.