json_validate()仅校验json语法和深度,不解析数据,适用于api预检、日志清洗等场景;需与json_decode()的$depth和$flags一致,php 8.2-需用polyfill并显式传参。

json_validate() 不解析数据,只做语法和深度检查,适合在 json_decode() 前快速拦截非法输入。它不是 schema 校验工具,也不替代业务字段验证。
什么时候该用 json_validate() 而不是直接 json_decode()
你只需要知道“这串文本是不是合法 JSON”,且后续不一定立刻解码——比如 API 入口做请求体预检、日志字符串批量清洗、配置文件加载前轻量过滤。
- 若紧接着就要
json_decode($input),直接用json_decode($input, flags: JSON_THROW_ON_ERROR)更高效,避免重复解析 - 若只是丢给队列或存入 raw_log 表,但要求必须是 JSON 格式,这时
json_validate()省内存、无副作用 - 高频接口(如 LLM 的
/v1/chat/completions)建议用它做第一道门,失败直接 400,不进业务逻辑
json_validate() 的参数陷阱
三个参数看似简单,但 $depth 和 $flags 错配会导致校验通过、解码失败,尤其在嵌套深或含非法 UTF-8 的场景。
-
$depth必须 > 0,且要和后续json_decode()用的深度一致;默认 512,但大模型返回的 message 数组可能嵌套超 20 层,设太小会误判为非法 -
$flags目前只支持JSON_INVALID_UTF8_IGNORE;如果原始数据含损坏 UTF-8 字节,不加这个 flag 会直接返回false,而你可能想忽略并继续处理 - 错误时不抛异常,需手动调
json_last_error()和json_last_error_msg()查原因(比如JSON_ERROR_DEPTH还是JSON_ERROR_UTF8)
PHP 8.2 及更早版本怎么兼容
别手写 json_decode() + json_last_error() 那种老式 fallback,容易漏 JSON_THROW_ON_ERROR 或类型判断。
- 直接引入 Julien T. 提供的 polyfill,它自动检测原生函数是否存在,优先用内置实现
- 关键补丁:加了
is_string($json)检查,防止传入 int/float 导致json_decode()静默返回null却被误判为合法(json_validate("123")在 PHP 8.3 返回true,但你可能期待对象) - 调用时仍要显式传
$depth和$flags,否则 polyfill 默认 512 和 0,和原生行为对不上
它返回 true 并不意味着你能安全当数组用
json_validate('{ "count": 42 }') 返回 true,但解码后是 ['count' => 42],不是你想的 ['count' => '42'];数字、布尔、null 都算合法 JSON。
- 如果你的接口协议要求
messages是数组、temperature是 float,json_validate()完全不管这些——它只管括号配对、引号闭合、深度没爆 - 真正需要的是:先
json_validate()过滤掉明显坏数据,再json_decode()后用is_array()、is_float()或filter_var()做字段级检查 - 别依赖它防业务攻击,比如
{"model":"gpt-4","max_tokens":999999999999}完全合法,但可能拖垮你的下游服务
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











