json_decode()默认返回stdClass对象,需传true参数才得关联数组;解析失败静默返回null,须用json_last_error()检查;输入必须为UTF-8无BOM;大JSON需防内存溢出。
直接调用 json_decode($json) 会返回 stdClass 对象,不是你想要的关联数组。很多 PHP 开发者卡在这一步,一打印发现是 object,用 $arr['key'] 报错 —— 因为对象得用 ->key 访问。
解决办法很简单:第二个参数传 true:
json_decode($json, true)
这样才真正转成 PHP 关联数组。注意这个 true 是布尔值,不是字符串 "true",也不是数字 1(虽然 PHP 会松散转换,但显式写 true 更安全、可读)。
json_decode() 在 JSON 格式非法、编码不兼容(如含 BOM)、或超深度嵌套时,**静默返回 null**,不会抛异常。如果你没检查就直接用,后续操作大概率报 Trying to access array offset on value of type null 或 Call to a member function ... on null。
务
必配合 json_last_error() 验证:
json_decode($json, true)
json_last_error(),结果为 JSON_ERROR_NONE 才算成功JSON_ERROR_SYNTAX(语法错)、JSON_ERROR_UTF8(UTF-8 编码损坏,比如从 Windows 记事本复制的 JSON)示例判断逻辑:
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new InvalidArgumentException('Invalid JSON: ' . json_last_error_msg());
}
PHP 的 json_decode() 要求输入字符串必须是合法 UTF-8。如果 JSON 字符串本身含 GBK、ISO-8859-1 编码的中文,或文件开头有 UTF-8 BOM(\xEF\xBB\xBF),解析会失败或返回 null。
实操建议:
mb_detect_encoding($json, ['UTF-8', 'GB2312', 'GBK'], true) 粗略检测编码(注意:不 100% 可靠,仅作参考)$json = mb_convert_encoding($json, 'UTF-8', 'auto')(慎用,可能破坏原始数据)Content-Type: application/json; charset=utf-8,或文件保存为「UTF-8 无 BOM」格式$json = ltrim($json, "\xEF\xBB\xBF")
json_decode() 是一次性加载整个字符串进内存并递归解析的。遇到几 MB 的 JSON(比如导出日志、全量商品数据),容易触发 memory_limit 错误,或解析极慢。
应对策略:
memory_limit 是否足够,必要时临时调整:ini_set('memory_limit', '256M')
jsonstream 扩展或 JsonReader 类),但标准库不支持json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) 美化输出,方便肉眼排查结构最常被忽略的是:即使 JSON 看似“不大”,但含大量重复键或深层递归引用(虽然 JSON 规范不允许引用,但某些生成器会违规输出),也会导致解析器栈溢出或卡死 —— 这类问题只能靠 json_last_error() 捕获错误码 JSON_ERROR_DEPTH 或 JSON_ERROR_RECURSION 来定位。