json_decode返回null绝大多数不是json写错,而是输入字符串带病入场:含bom、非utf-8编码、控制字符、语法细节错误(单引号/尾逗号)、嵌套过深或被截断;必须用trim、mb_convert_encoding清洗并立即校验json_last_error()。

PHP 的 json_decode() 返回 null,**绝大多数情况不是 JSON 写错了,而是输入字符串本身“带病入场”**——它看似是 JSON,实则隐藏着编码、结构或环境层面的问题。该函数默认静默失败,不抛异常、不报 warning,只悄悄返回 null,极易误导排查方向。
UTF-8 编码不纯:BOM 或非 UTF-8 字符最常见
json_decode 严格要求输入必须是合法的 UTF-8 字符串。一旦开头存在 UTF-8 BOM(\xEF\xBB\xBF),或字符串实际是 GBK/GB2312 编码却未转换,解析就会失败。
- 用
ltrim($str, "\xEF\xBB\xBF")清除 UTF-8 BOM - 用
mb_convert_encoding($str, 'UTF-8', 'auto')自动识别并转码 - 避免直接用
utf8_encode(),它只对 ISO-8859-1 有效,对 GBK 可能乱码
JSON 字符串本身不合法
看似格式正确,实则存在 RFC 7159 不允许的细节问题:
- 使用单引号代替双引号:
{'name': 'Alice'}❌ - 末尾多逗号:
{"a": 1, "b": 2,}❌ - 中文或特殊字符未被正确 UTF-8 编码,导致出现非法字节序列
- 换行、制表符、不可见控制字符(如
\x00–\x1F)混入字符串中
建议用 trim($str, "\x00..\x1F\x7F") 清理控制字符,并用在线 JSON 校验工具辅助验证。
嵌套过深或数据被截断
PHP 默认最大解析深度为 512 层。若 JSON 结构极端嵌套(如生成式数据、递归树),会触发 JSON_ERROR_DEPTH 错误,返回 null。
- 调用后立即检查:
if (json_last_error() === JSON_ERROR_DEPTH) - 可手动提高深度限制:
json_decode($str, true, 1024) - 从文件、数据库或 HTTP 请求读取时,注意是否因字段长度限制、输出缓冲或传输中断导致 JSON 被截断(缺失结尾
}或])
没检查错误就直接用了
这是最隐蔽也最普遍的疏忽:开发者看到 json_decode() 返回 null,第一反应是“JSON 有问题”,却忘了它根本不会主动告诉你哪里不对。
- 每次调用后必须紧跟校验:
if (json_last_error() !== JSON_ERROR_NONE) - 用
json_last_error_msg()获取具体提示,例如:
"Control character error, possibly incorrectly encoded" 或
"Maximum stack depth exceeded" - 禁用
@错误抑制符,否则连 warning 都看不到
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











