如果你希望查询出来的关联表字段(例如 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();

总结与建议

方案

特点

适用场景

withJoin()

SQL 层面合并,性能较好

需要根据关联表字段排序、筛选时。

bind()

代码最优雅,逻辑清晰

最推荐。纯粹为了在列表中方便调用关联数据。

append()

灵活,可做复杂逻辑转换

字段需要经过额外计算(如拼接、格式化)后才显示时。

一句话建议: 如果只是想在列表里少写一层嵌套,请直接在模型的关联方法里使用 bind()