json_decode() 默认失败返回 null 而不报错,需立即调用 json_last_error() 判断是否为 json_error_none,或用 json_throw_on_error 抛异常;输入须清洗控制字符和 bom;大 json 需预检长度并限制深度。

json_decode() 返回 null 却没报错?检查 json_last_error() 和 json_last_error_msg()
PHP 的 json_decode() 在解析失败时默认静默返回 null,不抛异常,也不提示哪里错了。光靠判断返回值是否为 null 不够——你得主动查错误码。
- 每次调用
json_decode()后,立刻调用json_last_error():返回JSON_ERROR_NONE才算成功 - 想看具体错误文字?用
json_last_error_msg(),比如"Syntax error"、"Unexpected control character" - 注意:
json_last_error()是全局状态,如果中间夹了其他 JSON 操作(比如日志里也用了json_encode()),结果会被覆盖
中文乱码或控制字符导致解析失败?先清理输入再解码
常见现象:前端传来的 JSON 字符串含不可见控制字符(如 U+0000、U+2028、U+2029),或 UTF-8 BOM 头,json_decode() 直接失败且报错为 "Syntax error"。
- 用
trim()去首尾空白,再用正则剔除非法控制字符:preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $json) - 检测并移除 UTF-8 BOM:
ltrim($json, "\xEF\xBB\xBF") - 别直接对用户输入的
$_POST['data']或file_get_contents('php://input')调用json_decode(),先过一遍清洗
需要严格校验结构?用 json_decode($json, true, 512, JSON_THROW_ON_ERROR)
PHP 7.3+ 支持 JSON_THROW_ON_ERROR 标志,让解析失败时直接抛出 JsonException,比手动查错误码更直观,尤其适合 API 入口层。
PHP5学习对象教程由美国人古曼兹、贝肯、瑞桑斯编著,简张桂翻译,电子工业出版社于2007年12月1日出版的关于PHP5应用程序的技术类图书。该书全面介绍了PHP 5中的新功能、编程方法及设计模式,还分析阐述了PHP 5中新的数据库连接处理、错误处理和XML处理等机制,帮助读者系统了解、熟练掌握和高效应用PHP。
- 必须配合
try/catch使用,否则脚本中断;错误类型是JsonException,不是Exception的子类(PHP 7.3–8.0) - 第三个参数
$depth默认 512,嵌套太深会报"Maximum stack depth exceeded",根据实际结构调整 - 注意:
JSON_THROW_ON_ERROR不影响json_encode(),只作用于json_decode()
解析大 JSON 时内存爆掉?限制大小 + 流式预检
json_decode() 会把整个字符串加载进内存再解析,遇到几 MB 的 JSON 容易触发 memory_limit 错误,且无法提前知道是否合法。
立即学习“PHP免费学习笔记(深入)”;
- 先用
strlen($json)或mb_strlen($json, '8bit')检查长度,超阈值(如 2MB)直接拒绝 - 用
json_decode($json, false, 1, JSON_PARTIAL_OUTPUT_ON_ERROR)(PHP 7.3+)可避免因部分字段非法导致全盘失败,但需自行处理缺失字段 - 真正的大数据场景(如日志导入),别硬解 JSON,改用流式解析器(如
ext-jsond或第三方库json-streaming-parser)
最常被忽略的是:错误码查询必须紧挨着 json_decode() 调用,中间不能穿插任何其他 JSON 函数;另外,json_last_error_msg() 返回的字符串不是 always UTF-8,某些旧版本 PHP 会返回 ISO-8859-1 编码,打印前最好 mb_convert_encoding(..., 'UTF-8') 一下。










