最直接的方式是用(array)强制转换,仅转换public属性且不递归;深层嵌套需自定义object_to_array()函数递归处理,避免json_encode/json_decode带来的精度丢失、类型破坏和性能问题。

stdClass 转数组:用 (array) 强制转换最直接
PHP 中把 stdClass 对象转成数组,最常用也最轻量的方式就是类型强制转换:(array)。它能快速把对象的 public 属性变成关联数组的键值对,不触发任何魔术方法,也不依赖扩展。
但要注意:这只做「浅转换」——嵌套的 stdClass 实例不会自动递归转成子数组,仍保持为对象。
- 适用场景:单层 JSON 解析结果(
json_decode($json)默认返回stdClass),且你确定结构扁平 - 不适用:含多层对象、有 protected/private 属性、或需要保留原始键顺序(PHP 7.4+ 关联数组有序,但老版本不保证)
- 示例:
$obj = json_decode('{"name":"Alice","age":30}'); $arr = (array) $obj; // 结果:['name' => 'Alice', 'age' => 30]
深层嵌套对象要递归转换?自己写个 object_to_array()
一旦 stdClass 里还包着对象(比如 JSON 多层嵌套、API 返回复杂结构),(array) 就不够用了。这时得手动递归处理,核心逻辑是判断每个值是否为 stdClass 或其他对象,再决定是否继续转换。
- 别直接用
json_encode() + json_decode(..., true):虽然能“曲线救国”,但会丢精度(如float变字符串、大整数溢出)、破坏类型(null和空字符串边界模糊)、且性能差一截 - 推荐写一个简洁函数,用
is_object()和get_object_vars()配合递归:function object_to_array($obj) { if (!is_object($obj) && !is_array($obj)) return $obj; if (is_object($obj)) $obj = get_object_vars($obj); return array_map('object_to_array', $obj); } -
get_object_vars()只取 public 属性,符合绝大多数stdClass使用场景;若遇到自定义类且含 protected 属性,就得换 Reflection,但那已超出stdClass的范畴
为什么不用 json_decode(json_encode($obj), true)?
这招看似一行解决,实际埋了三个常见坑:
立即学习“PHP免费学习笔记(深入)”;
- 浮点数精度丢失:
1234567890123456789.123经过 JSON 编解码可能变成1234567890123456768(JSON 数字精度限制) -
null值在某些旧版 PHP 的json_encode中会被跳过,导致数组 key 缺失 - 如果对象里有资源(resource)、闭包(Closure)或循环引用,
json_encode()直接报错或返回false,整个流程中断 - 性能上,序列化 + 反序列化比纯内存遍历慢 3–5 倍(实测千级嵌套结构)
注意 stdClass 和数组在 PHP 里的行为差异
转完不是万事大吉。有些代码会假设数组支持 isset($arr['key']) 或 empty($arr),但如果你忘了转换或部分没转透,运行时就可能出错。
-
isset($obj->key)在对象上有效,isset($arr['key'])在数组上才有效;混用会静默失败 -
empty($obj)对非空stdClass返回true(因对象无属性时才为 empty),而empty($arr)看长度——这点极易被忽略 - foreach 遍历时,
stdClass只遍历 public 属性,数组遍历所有键;若中间某层漏转,foreach 行为会突变



















