ThinkPHP6模型转数组需区分对象层级与转换深度:toArray()仅浅层转换;深层需json_encode+json_decode(true);避免冗余Collection::make()。

ThinkPHP6 中模型数据集转数组,核心是分清“对象层级”和“转换深度”。直接调用 toArray() 最常用,但它只做浅层转换;遇到关联模型、嵌套集合或需要纯数组结构时,就得配合其他方式。
基础转换:用 toArray() 获取当前层级数组
模型查询返回的是 Collection 对象(如 think\model\Collection),它本身支持数组式访问,但真正要转成 PHP 原生数组,toArray() 是首选方法:
-
User::select()->toArray()→ 把整批用户转为二维数组 -
User::find(1)->toArray()→ 把单个模型实例转为一维数组 - 支持链式控制字段:
User::select()->hidden(['password'])->append(['status_text'])->toArray()
注意:这个方法不会递归处理 with('profile') 这类关联模型。如果 $user['profile'] 是一个 Model 对象,它在数组里仍是对象,不是数组。
深层转换:用 json_encode + json_decode(true) 穿透所有层级
当必须确保结果里没有对象(比如传给前端、写日志、做 array_merge),推荐走 JSON 序列化通道:
立即学习“PHP免费学习笔记(深入)”;
$data = User::with('roles')->select();$plainArray = json_decode(json_encode($data), true);
这种方式能自动把模型、关联模型、Carbon 时间对象、获取器(accessor)返回值都转成对应格式的数组元素。缺点是轻微性能开销,但对几百条以内的数据完全无感。
⚠️ 不适用场景:模型中存了闭包、资源句柄或 PDO 实例(正常业务模型不该这么设计)。
按需提取:结合原生函数做数组加工
转成数组后,高频操作基本靠 PHP 原生函数,ThinkPHP 并不封装替代:
- 取某列值:
$ids = array_column($users, 'id'); - 去重并重排索引:
$uniqueIds = array_values(array_unique($ids)); - 安全判断存在:
in_array($targetId, $ids, true)(开启 strict 防止字符串 '1' 匹配整数 1) - 条件筛选:
$active = array_filter($users, fn($u) => $u['status'] === 1);
这些函数可直接作用于 toArray() 或 json_decode 得到的纯数组,无需额外适配。
避免踩坑:Collection::make() 不要乱套
有人习惯把已有的 Collection 再包一层 Collection::make(),这是冗余且危险的:
-
Db::name('user')->select()返回的就是Collection,再套Collection::make()会生成嵌套集合 -
toArray()后结构可能错乱,比如变成[0 => [0 => [...]]] - 仅在手动构造原始数组(非模型对象)时,才需
Collection::make($arr)来获得集合能力
判断是否为空也别用 empty(),统一用 $users->isEmpty()。



















