json_encode() 返回 null 主因是编码非 UTF-8、含资源类型、循环引用或对象未实现 JsonSerializable;加 JSON_THROW_ON_ERROR 可显式报错,中文不转义需配合 JSON_UNESCAPED_UNICODE 且确保输入为 UTF-8。

json_encode() 为什么返回 null?
不是数据有问题,大概率是编码或类型不兼容。PHP 的 json_encode() 对非 UTF-8 字符串、资源类型、循环引用、不可序列化的对象直接返回 null,且默认不报错。
- 中文乱码或含 GBK 字符时,先用
mb_convert_encoding($data, 'UTF-8', 'AUTO')转码 - 检查是否有
resource(比如未关闭的fopen()句柄),这类值无法 JSON 化 - 对象里有私有/受保护属性但没实现
JsonSerializable接口,也会静默失败 - 加
JSON_THROW_ON_ERROR选项让错误显性化:json_encode($data, JSON_THROW_ON_ERROR)
中文不转义成 \uXXXX 怎么办?
默认情况下 json_encode() 会把中文转成 Unicode 转义序列(如 "\u4f60\u597d"),前端看着费劲,也增大体积。
- PHP 5.4+ 直接加
JSON_UNESCAPED_UNICODE标志:json_encode($data, JSON_UNESCAPED_UNICODE) - 注意:如果源字符串本身不是 UTF-8,加这个标志反而导致乱码,务必先确保编码统一
- 旧版 PHP(
数组变对象还是保持索引数组?
json_encode() 判定“关联数组”和“索引数组”的逻辑很实际:只要键名不是从 0 开始的连续整数,就编码为 JSON 对象({});否则为数组([])。
- 常见陷阱:
['a' => 1, 0 => 2]是关联数组 → 输出{"a":1,"0":2},不是数组 - 想强制转数组?用
array_values($arr)重排键名,再json_encode() - 想强制转对象?给纯索引数组加个非数字键,或用
(object)$arr转成 StdClass - 注意:空数组
[]和空对象{}在 JS 里行为差异大,后端接口约定要明确
日期、浮点数、NaN 这些怎么安全处理?
PHP 原生类型和 JSON 规范之间存在语义断层。比如 DateTime 对象默认变成空对象 {},INF/NAN 直接触发 null 或警告。
立即学习“PHP免费学习笔记(深入)”;
- 日期统一转字符串:
$date->format('c')(ISO 8601)或'Y-m-d H:i:s',别依赖自动转换 - 浮点数精度问题:
json_encode(0.1 + 0.2)可能输出0.30000000000000004,敏感场景建议四舍五入或转字符串 -
INF、-INF、NAN默认不被支持,可用is_infinite()/is_nan()检查后替换为null或自定义标记 - 如果项目大量用特殊类型,考虑封装一层
safe_json_encode()做预处理
最常被忽略的是编码一致性——哪怕用了 JSON_UNESCAPED_UNICODE,只要输入字符串是 GBK 或混合编码,结果仍是错的。验证方式很简单:json_last_error() === JSON_ERROR_NONE 必须为真,不能只看输出是不是 null。











