json_decode返回NULL的首要原因是JSON字符串不符合标准,如使用单引号、尾随逗号或非法UTF-8字符;应通过json_last_error()定位错误,并确保输入为双引号包裹的合法UTF-8 JSON。

PHP 的 json_decode() 函数严格遵循 JSON 标准,而标准明确规定:字符串必须用双引号(")包裹,单引号(')是非法的。只要出现单引号,解析就会失败,返回 null,并触发 JSON_ERROR_SYNTAX 错误。
JSON 规范不支持单引号
这不是 PHP 的限制,而是整个 JSON 格式的硬性要求。RFC 7159 和 ECMA-404 都明确定义:键名和字符串值必须使用双引号包围。例如:
- ❌ 错误(单引号):
{'name': 'Alice'} - ✅ 正确(双引号):
{"name": "Alice"}
哪怕只有一处用了单引号,整个字符串就不再属于合法 JSON,json_decode() 会直接拒绝解析。
常见出错场景
单引号问题多出现在以下几种情况:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
立即学习“PHP免费学习笔记(深入)”;
- 前端 JavaScript 对象被错误地当 JSON 字符串传给 PHP(如
JSON.stringify()没调用,直接传了对象字面量) - 后端拼接字符串时手误写成单引号,比如:
$json = "{'id': 123}"; - 从日志、配置文件或旧系统导出的数据未标准化,保留了类 Python 或 JS 的单引号习惯
- 调试时用
var_dump()或print_r()看到带单引号的输出,误以为那是原始 JSON 字符串(实际是 PHP 数组的打印格式)
如何快速验证和定位
不要靠肉眼判断,用工具确认:
- 调用
json_decode($str, true)后立刻检查:if (json_last_error() !== JSON_ERROR_NONE) { echo json_last_error_msg(); } - 错误提示通常是
"Syntax error, malformed JSON"或明确指出"Expecting property name enclosed in double quotes" - 把字符串粘贴到在线校验器(如 jsonlint.com)——单引号会立刻标红
临时修复方案(慎用)
如果数据源不可控,且你必须兼容单引号格式,可做预处理(但不推荐长期依赖):
- 简单替换(仅适用于无嵌套引号的干净数据):
str_replace("'", '"', $str) - 更稳妥的正则替换(处理键和值中的单引号):
preg_replace('/(? - 注意:若字符串内部本身含单引号(如
O'Reilly),盲目替换会破坏语义,应优先推动上游修正格式


















