PHP对象转数组需按场景选择方法:仅公有属性用get_object_vars();需穿透访问限制可用json_encode+json_decode;复杂嵌套结构需反射+递归;长期项目推荐类内实现toArray()方法。

PHP接口返回的对象转数组,核心是看你要保留什么、舍弃什么——是只要公开字段快速响应,还是需要完整结构包括私有属性,又或者对象里还嵌套了其他对象。不同场景对应不同方法,选错容易丢数据或出错。
只取公有属性,简单干净用 get_object_vars()
这是最轻量、最安全的方式,适合API输出时只暴露明确定义的 public 字段。
- 它只返回当前作用域下可直接访问的公有属性,键名就是原始属性名,无前缀、无干扰
- 不处理 protected/private 属性,也不递归展开子对象——子对象仍为对象形态
- 如果类用了 __get() 魔术方法,该函数无法读取动态属性,需在类内提供显式 getter 或 toArray() 方法
想绕过访问限制,但能接受格式简化就用 json_encode + json_decode
把对象先转成 JSON 字符串再解码为关联数组,能“穿透” private/protected 限制,前提是属性可序列化。
- 执行 $arr = json_decode(json_encode($obj), true);
- DateTime、SimpleXMLElement 等对象会被转成字符串;资源(resource)、闭包(Closure)、循环引用会失败,json_encode 返回 false
- 所有类信息丢失,结果全是 stdClass 或普通数组,适合纯数据传输,不适合反向重建原对象
需要完整结构(含私有/受保护属性)且支持嵌套,就得用反射+递归
当对象结构复杂、含继承、含嵌套对象或数组,又必须保留全部字段时,强制类型转换和 get_object_vars 都不够用。
立即学习“PHP免费学习笔记(深入)”;
- 用 ReflectionClass 获取所有属性(public/protected/private),调用 setAccessible(true) 读值
- 对每个属性值判断类型:是对象就递归处理,是数组就遍历元素再递归,是基础类型就直接保留
- 键名按可见性还原:public 保持原名,protected 加 \0*\0 前缀,private 加 \0ClassName\0 前缀(如需统一键名,可正则清理)
长期维护项目建议类内实现 toArray() 方法
把转换逻辑收口到业务类中,既可控又易测试,还能配合隐藏字段、追加字段、格式化等需求。
- 在模型类里定义 public function toArray() { … }
- 内部可组合 get_object_vars()、手动提取私有属性、调用子对象的 toArray()、过滤敏感字段等
- Laravel Eloquent 模型已内置此能力,支持 $hidden、$appends、$casts 等配置,直接调用 ->toArray() 即可



















