php json_encode/json_decode高频踩坑:中文默认转\uxxxx,需json_unescaped_unicode;null处理需预处理或json_filter_null;大数转字符串防js精度丢失;嵌套过深、循环引用、非法utf-8致返回null,须用json_last_error精准定位。

PHP 的 json_encode 和 json_decode 看似简单,但实际开发中高频踩坑。多数问题不报错、不抛异常,只默默返回 false 或 null,导致数据丢失或前端解析失败。
中文被转成 \uXXXX 形式
默认情况下,json_encode 会把中文字符转义为 Unicode 序列(如 "\u5f20\u4e09"),不是乱码,但可读性差、调试困难。
- 必须加
JSON_UNESCAPED_UNICODE参数才能输出原生中文 - 该参数 PHP ≥ 5.4 才支持;老版本需手动递归
mb_convert_encoding - 脚本文件本身要存为 UTF-8 无 BOM 格式,否则即使加了参数也可能失败
- 响应头建议显式声明:
header('Content-Type: application/json; charset=utf-8');
空值(null)处理不符合预期
json_encode 默认保留 null,输出 {"name":null}。但有些接口把 null 当“字段不存在”,而空字符串 "" 才代表“存在且为空”。
- 用
array_walk_recursive预处理:将null替换为''或0(按业务定) - 用
JSON_FILTER_NULL可直接过滤掉null键值对(PHP ≥ 7.3) - 注意
JSON_FORCE_OBJECT会让空数组[]变成空对象{},某些 Java 后端会判为类型不匹配
浮点数精度丢失和大整数截断
PHP 浮点运算本身有精度误差,json_encode 不做修正:
-
8.10可能变成8.0999999999999996—— 金额类字段建议用字符串存储或number_format($val, 2, '.', '') - 超 JavaScript 安全整数范围(2⁵³−1)的大 ID(如雪花 ID)会被前端 JS 自动转成错误数值 —— 务必强制转字符串:
'id' => (string)$id
嵌套过深、循环引用、非法字符
json_decode 返回 null 却不报错?大概率是以下三种情况之一:
-
嵌套太深:默认最大深度 512 层,超限返回
null,json_last_error()返回JSON_ERROR_DEPTH -
循环引用:对象 A 持有 B,B 又持有 A,
json_encode直接报"Recursion detected"(PHP ≥ 7.3 可用JSON_PARTIAL_OUTPUT_ON_ERROR降级处理) -
非法 UTF-8 或 BOM 头:数据库或文件读取的字符串含 GBK 字符、UTF-8 BOM(
\xEF\xBB\xBF)、控制字符等,json_encode返回false,json_last_error()为JSON_ERROR_UTF8
解码后类型混淆与错误检查缺失
json_decode($str) 默认返回对象(stdClass),不是数组,容易 foreach 报错;而 json_decode($str, true) 才返回关联数组。
- 永远不要忽略返回值检查:
if ($data === null && json_last_error() !== JSON_ERROR_NONE) -
null有两种可能:原始 JSON 就是null,或解码失败 —— 必须结合json_last_error()判断 - 常见错误码:
JSON_ERROR_SYNTAX(语法错,如单引号、尾逗号)、JSON_ERROR_DEPTH(嵌套深)、JSON_ERROR_UTF8(编码脏)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











