PHP解析JSON返回null是明确错误信号,需立即调用json_last_error()判断错误码:JSON_ERROR_NONE为成功,非零值对应语法、UTF-8编码(含BOM/控制字符)、深度超限等问题;须清除BOM、统一转UTF-8、验证字符串完整性,并推荐启用JSON_THROW_ON_ERROR抛异常。

PHP 8 解析 JSON 返回 null,不是“没数据”,而是明确报错信号。它不抛异常、不打日志、不中断流程,只安静地返回 null——这恰恰是最容易被忽略的故障点。关键在于:**必须立刻查错误码,不能只判空**。
一、先看错误码,别猜原因
调用 json_decode() 后,下一行就必须调用 json_last_error():
-
JSON_ERROR_NONE(0)→ 解析成功,可放心用 -
JSON_ERROR_SYNTAX→ 字符串根本不是合法 JSON:常见于前端拼错引号、API 返回了 HTML 错误页(如 502)、日志混入非 JSON 内容 -
JSON_ERROR_UTF8→ 编码问题最典型:含 UTF-8 BOM(\xEF\xBB\xBF)、GBK 字节混入、或控制字符(\0、\t、\r) -
JSON_ERROR_DEPTH→ 嵌套太深,默认限 512 层;树形结构或配置项多时,需显式传第三参数:json_decode($json, true, 1024)
二、BOM 和编码是高频雷区
很多编辑器(尤其是 Windows 下的 Notepad++、VS Code 未设 UTF-8 无 BOM)保存 PHP 文件时自动加 BOM,一旦 include 或 require 这类文件,输出就会提前吐出 \xEF\xBB\xBF,导致后续 json_encode() 输出带 BOM 的 JSON,前端 JSON.parse() 直接失败。
- 清除 BOM:
$json = ltrim($json, "\xEF\xBB\xBF"); - 统一转 UTF-8:
$json = mb_convert_encoding($json, 'UTF-8', 'auto'); - 检测原始编码:
mb_detect_encoding($json, ['UTF-8', 'GBK', 'BIG5'], true)
三、检查输入字符串是否完整
JSON 被截断比想象中更常见:cURL 超时、MySQL TEXT 字段长度不足、输出缓冲未 flush、甚至 Nginx proxy_buffer_size 太小,都可能导致 {...} 变成 {...。
立即学习“PHP免费学习笔记(深入)”;
- 看结尾:
substr($json, -3)是否为"}"或"]" - 比长度:
strlen($json)是否明显小于预期(比如应有 2000 字节却只有 1024) - cURL 场景下,确认
curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200且Content-Length与实际响应体一致
四、启用异常模式,让错误浮出水面
PHP 7.3+ 支持 JSON_THROW_ON_ERROR,推荐在开发和测试环境强制开启:
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);- 配合
try-catch捕获JsonException,错误信息直接包含上下文 - 上线后可降级为
JSON_INVALID_UTF8_IGNORE或JSON_INVALID_UTF8_SUBSTITUTE容错处理
不复杂但容易忽略。核心就三点:查错误码、清 BOM、验完整性。



















