PHP中JSON双重编码指数据被多次json_encode导致解码后仍为字符串,需先判断类型再分两次json_decode:首次解码为字符串,二次加true转关联数组,避免直接foreach报错。

PHP中JSON字符串双重编码,本质是数据被多 encode 了一次,导致你拿到的不是数组,而是一个“长得像JSON的字符串”。直接 foreach 就会报 Invalid argument supplied for foreach()。解决核心就一条:**识别是否已双重编码,再决定解码次数**。
怎么判断是不是双重编码?
最直接的办法是用 var_dump() 或 echo gettype() 看变量类型:
- 如果
json_decode($str, true)后得到的是 string(比如输出string(56) "{"6":{"files":[],...}}"),说明它还是个JSON字符串,没真正变成数组——这就是双重编码。 - 如果解码后是 array 或 object,那说明只编码了一次,一次解码就够了。
正确解法:按需两次解码
确认是双重编码后,不能跳过第一次解码。必须分两步走:
- 第一步:把数据库或接口返回的原始值(字符串)用
json_decode($str)解成 PHP 字符串(或对象); - 第二步:再对这个结果调用
json_decode(..., true),转成关联数组。
写成一行就是:
立即学习“PHP免费学习笔记(深入)”;
$data = json_decode(json_decode($rawString, false), true);
注意第二个 json_decode 必须加 true,否则返回对象,后续处理仍不方便。
怎么避免下次再出现?
双重编码多发生在老项目或手动拼接场景,预防比修复更重要:
- 存入数据库前,别对已经是 JSON 字符串的字段再
json_encode(); - 用 ORM 时查文档,确认它是否自动反序列化 JSON 字段(如 Laravel 的
$casts、ThinkPHP 的json类型字段); - 前端传来的数据,用
file_get_contents('php://input')或框架原生请求体方法获取原始字符串,不要用$_POST直接取(可能已被自动解析或转义); - 调试时养成习惯:先
var_dump($input),再决定解码逻辑,不盲目套一层json_decode。
附:常见错误操作
这些写法看似省事,实际埋雷:
-
foreach (json_decode($str, true) as ...)→ 如果 $str 是双重编码,这里传给 foreach 的是字符串,直接报错; -
json_decode(json_encode($str))→ 无意义的来回编解码,还可能丢失精度或引入转义; - 在 ThinkPHP 或 Laravel 中混用
json($data)和json_encode($data)→ 导致响应体变成"{...}"(带外层引号),前端收到的是字符串而非对象。



















