PHP解析JSON需重点防范解码失败返回null、中文BOM乱码、大整数精度丢失、嵌套访问报错四类问题,应检查json_last_error()、去除BOM、启用JSON_BIGINT_AS_STRING、使用??或安全访问函数。

PHP处理API返回的JSON数组时,看似简单,实则容易在编码、类型、嵌套和错误处理上栽跟头。最常被忽略的是JSON解码失败后静默返回null,以及中文乱码、数字精度丢失、深层嵌套访问出错等问题。
JSON解码失败却不报错,数据直接变null
PHP的json_decode()默认失败时返回null,且不抛异常。如果API返回空响应、HTML错误页(如502)、或含BOM的UTF-8字符串,解码就会静默失败。
- 始终检查解码结果:
$data = json_decode($json, true); if ($data === null && json_last_error() !== JSON_ERROR_NONE) { /* 处理错误 */ } - 用
json_last_error_msg()获取具体原因,比如“Syntax error”、“Malformed UTF-8 characters” - 调试时可先
var_dump($json)确认原始字符串是否符合JSON格式,尤其注意换行、单引号、未转义的双引号
中文乱码或特殊字符变问号/空格
根源通常是API返回的JSON声明了UTF-8但实际含BOM,或PHP脚本自身编码不是UTF-8,或输出前被二次编码。
- 接收后立刻用
mb_convert_encoding($json, 'UTF-8', 'auto')统一编码,再解码 - 用
trim($json, "\xEF\xBB\xBF")手动去除UTF-8 BOM(常见于Windows生成的JSON) - 避免对已解码的数组再用
urlencode()或htmlentities(),除非明确需要
数字被转成浮点,精度丢失(如ID、金额)
PHP 7.1+ 支持JSON_BIGINT_AS_STRING选项,但默认仍把大整数(如16位以上订单号、微信OpenID)转为浮点,导致末尾变0或科学计数法。
立即学习“PHP免费学习笔记(深入)”;
- 解码时强制转字符串:
json_decode($json, true, 512, JSON_BIGINT_AS_STRING) - 对关键字段(如
id、openid、price)解码后手动检查类型:is_string($data['id']) && ctype_digit($data['id']) - 金额类数据建议统一用字符串存储,运算前转
bcadd()等BCMath函数,避免浮点误差
嵌套数组访问报Notice:Undefined index或Trying to access array offset on value of type null
API结构可能不稳定——某次返回"user": {"name": "A"},下次变成"user": null,直接写$data['user']['name']就崩。
- 用
??空合并操作符:$name = $data['user']['name'] ?? '未知用户'; - 对多层结构,封装安全访问函数:
function arr_get($arr, $path, $default = null) { foreach (explode('.', $path) as $key) { if (!is_array($arr) || !isset($arr[$key])) return $default; $arr = $arr[$key]; } return $arr; } // 用法:arr_get($data, 'user.profile.avatar') - 必要时用
isset()或array_key_exists()逐层判断,别图省事链式调用
不复杂但容易忽略——多加一行错误检查、一次编码清理、一个空值兜底,就能避开90%的JSON解析翻车现场。



















