PHP对象转数组最直接的方法是用(array)强制类型转换,但它对多层嵌套、私有属性、动态属性等复杂结构支持有限;真正可靠的方式是结合反射或递归处理,尤其当对象含私有/受保护属性、继承关系或循环引用时。

PHP对象转数组最直接的方法是用(array)强制类型转换,但它对多层嵌套、私有属性、动态属性等复杂结构支持有限。真正可靠的方式是结合反射(Reflection)或递归处理,尤其当对象含私有/受保护属性、继承关系或循环引用时。
基础转换:简单对象用强制类型转换
适用于公有属性、无嵌套的stdClass或普通类实例:
- 直接写 (array)$obj,会把公有属性转为键值对
- 注意:私有属性会带类名前缀(如 "\0ClassName\0property"),受保护属性同理,直接转后键名不可读
- 如果对象实现了 JsonSerializable 接口,建议先 json_decode(json_encode($obj), true),兼容性更好
深度转换:处理私有/受保护属性和嵌套对象
用反射(ReflectionClass)遍历所有属性,无论访问控制符,再递归处理值:
- 创建一个递归函数,对每个属性值判断是否为对象 —— 是则继续调用自身,否则保留原值
- 用 $ref->getProperties() 获取全部属性,调用 $prop->setAccessible(true) 读取私有/受保护值
- 需手动跳过静态属性和未初始化的属性($prop->isStatic() 或 !$prop->isInitialized($obj))
实用封装:一个健壮的 to_array() 辅助方法
可直接复用的静态方法,支持对象、数组、基本类型混合结构:
立即学习“PHP免费学习笔记(深入)”;
- 输入非对象直接返回(如字符串、数字、数组保持不变)
- 遇到对象,用反射提取所有可访问属性,并对值递归调用自身
- 内置循环引用检测(用 spl_object_id 记录已处理对象,避免无限递归)
- 可选参数控制是否保留原始类名前缀、是否展开 JSON 字符串等
避坑提醒:这些情况要特别注意
实际项目中容易出错的点:
- Laravel 的 Eloquent 模型不要直接 (array),应调用 $model->toArray(),它已处理了隐藏字段、访问器、关联关系
- SimpleXML 对象需先 json_decode(json_encode($xml), true),否则 (array) 只得空数组
- 含 Closure、Resource 或 PDOStatement 的对象无法安全转数组,需提前过滤或抛出异常
- 日期对象(DateTime)默认转成对象数组,建议在递归中统一转为格式化字符串(如 ->format('Y-m-d H:i:s'))



















