
json_encode() 为什么返回 NULL?
不是数据有问题,大概率是编码或类型不兼容。json_encode() 对非 UTF-8 字符串、资源型变量、循环引用对象会静默失败,返回 null。用 json_last_error_msg() 看真实原因比猜快得多。
- 中文乱码?先用
mb_convert_encoding($str, 'UTF-8', 'GBK')转码,别依赖 mbstring 自动检测 - 对象里有 private 属性或闭包?默认不序列化。要么加
JsonSerializable接口,要么提前用get_object_vars()提纯 - 用了
SimplexmlElement或PDOStatement?它们不是普通对象,json_encode()不认,得先转成数组:json_encode(json_decode(json_encode($xml), true))
对象转字符串要不要用 json_encode()?
要看“字符串”用途。如果目标是网络传输、存日志、给前端用,json_encode() 是标准解;如果只是调试打印,var_export() 或 print_r($obj, true) 更直观,且保留类型信息。
-
json_encode($obj, JSON_UNESCAPED_UNICODE)避免中文变 uXXXX -
json_encode($obj, JSON_INVALID_UTF8_IGNORE)(php 7.2+)可跳过非法 UTF-8 字节,但慎用——可能掩盖源头问题 - 想保留浮点精度?
JSON_PRESERVE_ZERO_FRACTION对整数无效,它只影响1.0这类带 .0 的数字
字符串转 JSON 失败常见报错
错误信息里带 JSON_ERROR_SYNTAX,基本就是字符串本身不是合法 JSON。别急着改 PHP 代码,先验证输入源。
- 前端传来的
$_POST['data']可能被 URL 解码或 magic quotes 搞坏,用json_decode(trim($input), true)+json_last_error()定位 - 从文件读的 JSON 带 bom?用
file_get_contents()后先ltrim($s, "xEFxBBxBF") - 用了单引号?JSON 只认双引号,
str_replace("'", '"', $s)是懒办法,但可能误伤内容里的单引号
性能和兼容性要注意什么?
json_encode() 和 json_decode() 在 PHP 7.4+ 有明显加速,但大对象仍可能触发内存限制。老项目跑在 PHP 5.6 上,别用 JSON_THROW_ON_ERROR——它不存在。
立即学习“PHP免费学习笔记(深入)”;
- 超大数组(>10 万项)转 JSON?考虑分块或流式输出,避免
Allowed memory size exhausted - 需要兼容 PHP 5.2?别用
JSON_PARTIAL_OUTPUT_ON_ERROR,也别指望stdClass能自动转关联数组,老老实实用(Array)$obj -
json_encode()默认不处理 NaN/INF,会返回false。真要支持,得自己预处理:is_nan($v) ? 'null' : $v
实际用的时候,最常卡住的不是语法,是字符编码混搭和对象内部状态不可序列化——这两点没检查清楚,光调参数没用。