(array)$obj最快但仅转public属性且不递归;json_encode+decode可递归但丢类型、不支持资源;反射可读private/protected;laravel的toarray()仅限eloquent模型。

用 (array) 强制转换最简单,但只处理一级属性
直接写 (array)$obj 是最快的方式,PHP 会把对象的 public 属性转成数组键值对,private 和 protected 属性会被忽略,且不会递归处理嵌套对象。
- 适用场景:对象结构扁平、所有要转的字段都是 public
- 注意:
__toString()或__get()不会被触发,纯属性映射 - 如果对象有同名的 public 属性和 magic getter,后者不会生效
- 示例:
$obj = new stdClass(); $obj->name = 'Alice'; $obj->data = (object)['id' => 123]; var_dump((array)$obj); // 输出:array(2) { ["name"]=> string(5) "Alice" ["data"]=> object(stdClass)#2 (1) { ["id"]=> int(123) } }
json_encode() + json_decode() 能递归展开,但丢类型、不支持资源
先 json_encode($obj) 再 json_decode(..., true),能穿透多层对象、数组混合结构,但所有数字键可能被转成字符串,DateTime 变成 ISO8601 字符串,resource 和 closure 会直接报错或丢失。
- 适合:临时调试、导出简单数据、不关心原始类型
- 风险:
json_encode()遇到不可序列化内容(如未实现JsonSerializable的自定义对象)会返回false,需判空 - 性能开销比强制转换大,频繁调用要注意
- 示例:
$arr = json_decode(json_encode($obj), true);
自己写递归函数控制细节,比如保留 private/protected 属性
PHP 对象的私有属性在数组转换后会带类名前缀,格式为 <p>PHP 对象的私有属性在数组转换后会带类名前缀,格式为 <code>\0ClassName\0propName。想完整还原,得用 get_object_vars() 结合 ReflectionObject 手动提取。
PHP 对象的私有属性在数组转换后会带类名前缀,格式为 \0ClassName\0propName。想完整还原,得用 get_object_vars() 结合 ReflectionObject 手动提取。
get_object_vars() 结合 ReflectionObject 手动提取。
-
get_object_vars($obj)只返回 public 属性,和(array)效果一致 - 要读 private/protected,必须用反射:
(new ReflectionObject($obj))->getProperties() - 遍历 property 时需调用
$prop->setAccessible(true)才能读值 - 递归处理值时,要判断是否为对象,避免无限循环(比如对象里引用自身)
Laravel 的 toArray() 方法不能直接复用,除非你用 Eloquent
很多人搜到 Laravel 文档里的 toArray(),但那是 Illuminate\Database\Eloquent\Model 类的方法,依赖模型内部的属性白名单($casts、$appends、$hidden)和 accessor 逻辑。普通对象调用会报 Fatal error: Call to undefined method。
- 如果你没在用 Eloquent,别尝试
$obj->toArray() - 即使用了 Eloquent,也要注意:它默认不包含关系对象,要显式调用
load()或配置$with - 第三方包如
spatie/array-to-object是反向操作,不解决当前问题
真正难的不是“怎么转”,而是“转完之后字段还在不在、类型还对不对、嵌套层级有没有断”。尤其当对象来自 API 响应或 ORM 查询结果时,属性可见性、动态属性、魔术方法都会让转换行为变得不透明。动手前先 var_dump(get_class($obj)) 和 print_r((array)$obj) 对比一眼,比直接套方案更省时间。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











