json_encode() 返回 null 主因是非 UTF-8 编码、资源类型、循环引用或不可序列化对象;需用 mb_check_encoding 验证编码、避免资源句柄、实现 JsonSerializable 接口,并用 json_last_error_msg() 定位错误。

json_encode() 为什么返回 null?
不是数据有问题,大概率是编码或类型不兼容。PHP 的 json_encode() 遇到非 UTF-8 字符、资源类型(如 mysqli 对象)、循环引用、或不可序列化的对象时,会静默失败并返回 null。
- 检查输入是否为纯 UTF-8:用
mb_check_encoding($data, 'UTF-8')验证,中文乱码或 GBK 字符串必须先转码:mb_convert_encoding($data, 'UTF-8', 'GBK') - 避免传入资源句柄(如
mysql_result、fopen()返回值),这些不能 JSON 化 - 对象需确保属性可访问(public)或实现了
JsonSerializable接口;否则默认只导出 public 属性,private/protected 被跳过 - 调试时加一句:
if (json_last_error() !== JSON_ERROR_NONE) { echo json_last_error_msg(); },能立刻定位失败原因
中文输出变成\uXXXX怎么办?
这是默认行为,不是 bug。PHP 5.4+ 的 json_encode() 默认对非 ASCII 字符做 Unicode 转义,浏览器能正常解析,但可读性差。
- 加
JSON_UNESCAPED_UNICODE标志即可保留原文:json_encode($data, JSON_UNESCAPED_UNICODE) - 注意:该标志在 PHP iconv() 或
mb_convert_encoding()配合正则“反解”,不推荐 - 如果用了
JSON_UNESCAPED_UNICODE还是乱码,说明原始字符串本身不是 UTF-8,得先统一编码
数组还是对象?怎么控制顶层结构?
json_encode() 是否输出 JSON 对象 {} 还是数组 [],取决于 PHP 数组的“是否为索引连续且从 0 开始”——它不看变量名,只看键结构。
- 关联数组(含字符串键)→ JSON 对象:
['name' => 'Alice', 'age' => 25]→{"name":"Alice","age":25} - 索引数组(数字键且连续)→ JSON 数组:
[1, 2, 3]→[1,2,3] - 但
[0 => 1, 2 => 3]键不连续 → 被当成关联数组 → 输出对象:{"0":1,"2":3} - 强制转对象:传入
(object)$arr;强制转数组:对对象用(array)$obj(注意 public 属性限制)
生产环境要注意的三个细节
本地跑通不等于线上安全,尤其涉及用户数据或 API 交互时。
立即学习“PHP免费学习笔记(深入)”;
- 永远过滤或转义用户输入再进
json_encode():比如 HTML 片段含<script></script>,虽不会执行,但可能破坏前端渲染逻辑 - 大数组慎用:深度嵌套或超长字符串会导致内存暴涨或超时,可用
JSON_PARTIAL_OUTPUT_ON_ERROR(PHP 7.3+)让出错时尽量返回部分结果 - 日期时间别直接
json_encode():DateTime对象默认转成空对象{},应提前格式化:$date->format('c')或实现JsonSerializable::jsonSerialize()
最常被忽略的是编码检测和错误检查——很多人只写 echo json_encode($data),却没加 json_last_error() 判断,出问题连日志都抓不到源头。



















