最稳妥方式是json_encode+json_decode,可处理所有属性可见性并自动展开嵌套;手动递归适合精细控制;强制类型转换(array)仅适用于简单public对象;反射机制用于高权限需求但性能较低。

直接用 json_encode + json_decode 最省事
这是处理多层嵌套对象最常用、也最稳妥的方式。它不挑属性可见性,public、protected、private 都能转出来,还能自动展开子对象和子数组。
写法很简单:
- 先调用 json_encode($obj) 把对象变成 JSON 字符串
- 再用 json_decode($json, true) 把字符串转成关联数组(第二个参数 true 很关键)
注意两点:对象里不能有 resource(比如数据库连接)、Closure(匿名函数),也不能有循环引用,否则 json_encode 会返回 false。DateTime 对象会被转成 ISO8601 字符串,不是 DateTime 实例了。
手动递归遍历适合精细控制
当你需要跳过某些字段、做类型预处理、或兼容不可 JSON 序列化的值时,就得自己写递归函数。
核心逻辑是:判断当前值是不是对象 → 是的话先用 get_object_vars() 拿出属性 → 对每个属性值再递归处理;如果是数组,也逐项递归;其他类型原样保留。
示例要点:
- 函数接收任意类型输入,统一判断 is_object() 或 is_array()
- 对对象优先尝试 __toArray() 或 jsonSerialize()(如果类实现了这些方法)
- 私有/受保护属性在 get_object_vars() 中拿不到,这时可配合 ReflectionClass 强制访问
强制类型转换 (array) 看似快但容易踩坑
写 (array)$obj 确实一行搞定,但它只是浅层转换,且键名带特殊前缀:protected 属性变成 \0*\0prop,private 变成 \0ClassName\0prop。这种数组后续用 isset() 或 array_key_exists() 都不方便,也不利于 JSON 输出或 API 返回。
只建议用于临时调试、或你明确知道对象结构简单且全是 public 属性的场景。
反射机制应对高权限需求
当对象用了 private/protected 属性,又不能改源码加 getter,还不能走 JSON 路线(比如含资源),就可以用 ReflectionClass。
步骤很清晰:
- 用 new ReflectionClass($obj) 创建反射实例
- 调用 getProperties() 获取全部属性(不管可见性)
- 对每个属性调 setAccessible(true),再用 getValue($obj) 拿值
- 对拿到的值继续递归处理(如果是对象或数组)
这种方式灵活度最高,但性能略低,也更重。日常开发中非必要不首选。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











