json_last_error()不报错,仅反馈最近一次JSON操作的错误码;判断json_decode()是否失败须结合其返回值与json_last_error()是否为JSON_ERROR_NONE,常见错误包括JSON_ERROR_SYNTAX(语法错误)、JSON_ERROR_UTF8(编码异常)和JSON_ERROR_DEPTH(嵌套过深)。

json_last_error() 本身不报错,它只是告诉你上一次 json_decode() 或 json_encode() 出了什么问题 —— 真正要解决的,是背后那几个高频错误码。
怎么判断是不是 json_decode() 失败了
别只看返回值是不是 null:PHP 在解析失败时统一返回 null,但原始 JSON 里本来就有 null 值,光靠 === null 无法区分。
必须搭配 json_last_error() 判断:
-
json_last_error() === JSON_ERROR_NONE→ 解析成功 -
json_last_error() !== JSON_ERROR_NONE→ 解析出错,再查具体类型 - 注意:
json_last_error()只反映「最近一次」JSON 操作的结果,中间穿插其他 JSON 调用会覆盖它
JSON_ERROR_SYNTAX(错误码 4):最常踩的坑
这不是 PHP 的 bug,是 JSON 字符串本身不合法。常见表现:json_decode() 返回 null,json_last_error() 是 4,json_last_error_msg() 提示 “Syntax error, malformed JSON”。
立即学习“PHP免费学习笔记(深入)”;
典型原因包括:
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
- 末尾多了一个逗号:
{"name":"Alice",} - 用了单引号:
{'name':'Alice'}(JSON 规范强制双引号) - 字符串里有未转义的换行或制表符:
{"msg":"hello\nworld"} - 中文引号、全角符号混入(比如从 Word 或微信粘贴过来)
- 响应被截断(如 cURL 超时、Nginx 缓冲区限制),导致 JSON 不完整
修复建议:用 json_validate($json)(PHP 8.3+)预检;低版本可用 json_decode($json, true) !== null && json_last_error() === JSON_ERROR_NONE 双重验证。
JSON_ERROR_UTF8(错误码 5):编码不对就直接跪
输入字符串看似正常,但内部含非 UTF-8 字节(比如 GBK、Windows-1252 编码的中文),json_decode() 会直接放弃并返回 null。
检查和修复步骤:
- 用
mb_detect_encoding($json, ['UTF-8', 'GBK', 'BIG5'], true)粗略探测编码 - 确认来源:API 响应头是否声明
Content-Type: application/json; charset=utf-8?没声明就默认按 UTF-8 解,错的概率极高 - 转换编码(谨慎):
$json = mb_convert_encoding($json, 'UTF-8', 'GBK'),但需确保原始编码可识别,否则可能引入乱码 - 更稳妥的做法:在接收端(如 cURL)强制指定
CURLOPT_ENCODING => 'UTF-8',或让上游服务保证输出 UTF-8
JSON_ERROR_DEPTH(错误码 1):嵌套太深不是数据问题,是配置问题
默认最大嵌套深度为 512 层,超出即报此错。实际项目中极少真有 500 层嵌套,更多是循环引用被误判(比如对象里存了自己),或 JSON 数据被恶意构造。
应对方式:
- 显式传入
$depth参数扩大限制:json_decode($json, true, 1024) - 但别无脑调高 —— 过大的
$depth会吃内存,且可能掩盖真实的数据结构缺陷 - 若确定是循环引用,需在序列化前清理(如用
JSON_THROW_ON_ERROR+ try/catch 捕获,或改用serialize()+unserialize()临时绕过) - PHP 7.3+ 支持
JSON_THROW_ON_ERROR标志,可让错误直接抛异常,比轮询json_last_error()更直观
真正容易被忽略的是:错误码本身不会告诉你哪一层崩了,也没有行号 —— 它只提示“超深”,你得结合数据来源和结构预期去反推。调试时,先用小样本验证结构,再逐步放大输入规模。


















