如果你希望查询出来的关联表字段(例如 user_name)直接平铺在主表的数据列表里,而不是嵌套在关联对象中(即不希望通过 $item['user']['name'] 访问,而是希望通过 $item['user_name'] 访问),在 ThinkPHP 6 中通常有以下三种处理方案:
1. 使用 withJoin() —— 最直接的“平铺”方案
withJoin 会在底层执行一个 SQL JOIN 查询。默认情况下,它会自动将关联表的字段合并到结果集中。
PHP
// 假设 Article 关联 User
$list = Article::withJoin([
'user' => ['nickname', 'email'] // 指定关联表字段
])->select();
// 这样查出来的 $list 里的每一项,可以直接访问:
// $item['nickname'] 而不需要 $item['user']['nickname']
2. 在模型中定义 bind() —— 关联属性绑定 (推荐)
如果你使用的是 with() (预载入查询),关联数据默认是嵌套的。你可以通过在主模型(如 Article)的关联定义中使用 bind() 方法,将关联表的字段“绑定”到主模型上。
模型定义 (Article.php):
PHP
public function user()
{
// 将关联表的 nickname 绑定到主模型,并起个别名 user_name
return $this->belongsTo(User::class, 'user_id')
->bind([
'user_name' => 'nickname',
'user_email' => 'email'
]);
}
控制器调用:
PHP
$list = Article::with(['user'])->select();
// 输出数据时,关联字段就像主表字段一样:
foreach ($list as $item) {
echo $item->title; // 主表字段
echo $item->user_name; // 关联表绑定过来的字段
}
3. 使用 append() 结合获取器 (模型层面处理)
如果你希望在转换为数组或 JSON 时自动增加这些字段,可以在模型里定义一个“虚拟字段”(获取器),并将其追加到输出中。
模型定义 (Article.php):
PHP
// 定义一个获取器
public function getUserNameAttr($value, $data)
{
return $this->user->nickname ?? '';
}
控制器调用:
PHP
$list = Article::with(['user'])->select()->append(['user_name']);
// 这样转换成数组后,结果里就会多出一个 user_name 字段
$array = $list->toArray();
总结与建议
一句话建议: 如果只是想在列表里少写一层嵌套,请直接在模型的关联方法里使用 bind()。