结论:json处理必须严格校验错误、清洗输入、统一编码和状态码。json_decode()返回null需立即查json_last_error();json_encode()返回false要检查数据可序列化性;输出前清缓冲、设header、加json_unescaped_unicode;访问嵌套字段用??或safe_get();http状态码须与实际结果一致。

直接说结论:不检查 json_encode() 和 json_decode() 的返回值、不查错误码、不清洗输入,就等于在生产环境裸奔。
json_decode() 返回 null?别只判断是否为 null
它返回 null 是明确失败信号,不是“可能没数据”。必须立刻调用 json_last_error() 看具体原因:
-
JSON_ERROR_SYNTAX:前端传了带单引号的 JSON、末尾逗号、混入 HTML 错误页(比如 502 页面) -
JSON_ERROR_UTF8:最常被忽略——输入含 UTF-8 BOM(\xEF\xBB\xBF)或 GBK 字节;先ltrim($json, "\xEF\xBB\xBF"),再mb_convert_encoding($json, 'UTF-8', 'auto') -
JSON_ERROR_DEPTH:默认最多解析 512 层嵌套;树形结构或深度配置要显式传第三参数:json_decode($json, true, 1024)
更省事的做法是加 JSON_THROW_ON_ERROR 标志(PHP 7.3+):json_decode($json, true, 512, JSON_THROW_ON_ERROR),失败直接抛 JsonException,不用手动查码——但得配 try/catch。
json_encode() 返回 false?检查数据本身是否“可序列化”
它返回 false 不是偶然,90% 是因为传了不可序列化的值:
- 资源类型(
resource),比如fopen()返回的句柄 - 闭包(
Closure)或含循环引用的对象/数组 - 非 UTF-8 编码字符串(如 GBK 中文),哪怕看着正常也会静默失败
务必用 === false 严格比较(别用 == false 或 !$result),然后立刻调 json_last_error_msg() 定位。对不确定数据,提前过滤:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
array_walk_recursive($data, function (&$v) {
if (is_resource($v)) $v = '[resource]';
elseif (is_object($v) && method_exists($v, '__toString')) $v = (string)$v;
});
中文乱码、输出空白、前端报 SyntaxError?源头都在输出体里
这些现象本质相同:响应体混入了非 JSON 内容。常见来源:
- PHP 文件本身带 UTF-8 BOM(VS Code 里选「UTF-8 无 BOM」保存)
- 脚本开头有空格、
echo、var_dump()或未捕获的 Notice/Waring - 开启了
display_errors,错误信息直接打到响应流里 - 用了
ob_start()但没清理,缓冲区残留内容
上线前必须关掉 display_errors,改用日志;接口入口加 ob_end_clean() 清缓冲;输出 JSON 前统一设头:header('Content-Type: application/json; charset=utf-8');中文要可读,编码时必须加 JSON_UNESCAPED_UNICODE。
访问嵌套字段总出错?别硬写 $data['a']['b']['c']
一旦某层缺失,就会触发 Notice: Undefined index 或 Invalid argument supplied for foreach()。安全写法只有两种:
- 用空合并操作符:
$title = $data['result']['files'][0]['title'] ?? 'N/A'; - 封装一个
safe_get()函数,支持点号路径:safe_get($data, 'result.files.0.title', 'default')
如果结构复杂且高频使用,建议在解码后立刻用 is_array() + isset() 做一次基础校验,比到处加 ?? 更利于定位哪一层断了。
真正容易被忽略的,是错误状态和 HTTP 状态码脱钩——json_encode() 失败却返回 200 OK,前端永远不知道是数据为空还是服务炸了。HTTP 状态码必须真实反映结果,这点比任何格式优化都重要。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










