Statement on glibc/iconv Vulnerability

json_validate

(PHP 8 >= 8.3.0)

json_validate检查一个字符串是否包含有效的JSON

说明

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

返回给定的 string 是否是语法上有效的 JSON。 如果 json_validate() 返回 truejson_decode() 在使用相同的 depthflags 时,将成功解码给定的字符串。

如果 json_validate() 返回 false,原因可以使用 json_last_error()json_last_error_msg() 获取。

如果解码后的 JSON 内容未被使用,json_validate() 相比于 json_decode() 使用了较少的内存,因为它不需要构建包含有效载荷的数组或对象结构。

警告

json_decode() 之前调用 json_validate() 将不必要地解析字符串两次, 因为 json_decode() 在解码过程中隐式地执行验证。

json_validate() 只有在解码后的 JSON 内容不会立即使用,但需要知道字符串是否包含有效的 JSON 时才有用。

参数

json

需要验证的字符串。

该函数仅适用于 UTF-8 编码字符串。

注意:

PHP 实现了 JSON 的一个超集,参考 » RFC 7159.

depth

解码结构的最大嵌套深度。 该值必须大于 0、 且小于或等于 2147483647

flags

当前只接受 JSON_INVALID_UTF8_IGNORE

返回值

如果给定字符串是语法有效的 JSON,则返回 true,否则返回 false

错误/异常

如果 depth 超出允许的范围,将抛出 ValueError

如果 flags 不是一个有效的 flag,将抛出 ValueError

示例

示例 #1 json_validate() 示例

<?php
var_dump
(json_validate('{ "test": { "foo": "bar" } }'));
var_dump(json_validate('{ "": "": "" } }'));
?>

以上示例会输出:

bool(true)
bool(false)

参见

add a note

User Contributed Notes 3 notes

up
12
Behrad
3 months ago
---------------- PHP < 8.3 ----------------

function json_validate(string $string): bool {
    json_decode($string);

    return json_last_error() === JSON_ERROR_NONE;
}

var_dump(json_validate('{ "test": { "foo": "bar" } }')); // true

---------------- PHP >= 8.3 ----------------

var_dump(json_validate('{ "test": { "foo": "bar" } }')); // true

Note: code from https://www.php.net/releases/8.3/en.php
up
4
Julien T.
2 months ago
Building upon Allan R.'s initial idea, I've developed an improved version of the json_validate function for those using PHP 8.2 and earlier versions. This function emulates the functionality introduced in PHP 8.3, providing an effective way to validate JSON strings in earlier PHP versions.

```php
if (!function_exists('json_validate')) {
    /**
     * Validates a JSON string.
     *
     * @param string $json The JSON string to validate.
     * @param int $depth Maximum depth. Must be greater than zero.
     * @param int $flags Bitmask of JSON decode options.
     * @return bool Returns true if the string is a valid JSON, otherwise false.
     */
    function json_validate($json, $depth = 512, $flags = 0) {
        if (!is_string($json)) {
            return false;
        }

        try {
            json_decode($json, false, $depth, $flags | JSON_THROW_ON_ERROR);
            return true;
        } catch (\JsonException $e) {
            return false;
        }
    }
}
```

Key Improvements:

- String Check: Added a validation to ensure the input is a string.
- Error Handling: Utilizes try-catch to effectively catch and handle JsonException.
- Backward Compatibility: Safely integrable in older PHP versions, automatically deferring to native functionality in PHP 8.3+.
up
1
Allan R.
2 months ago
Pre PHP 8.3, and future compatible, function/wrapper

---
if(!function_exists("json_validate")) {
    function json_validate() {
        try {
            json_decode($json, JSON_THROW_ON_ERROR);
            return true;
        } catch(\JsonException) {
            return false;
        }
    }
}
---

An issue with simply relying on json_last_error() == JSON_ERROR_NONE is if you have an error handler that catches errors or notices and throws them instead as  fx. \ErrorException

That would cause a call to json_decode(); to throw an exception exiting the scope of the function.
To Top