Skip to main content

将查询结果列表的键(key)指定为某个字段的值

在 Yii2 中,如果你想将查询结果列表的键(key)指定为某个字段的值(例如用 id 作为数组键),可以使用 indexBy() 方法。它支持查询构建器(yii\db\Query)和 ActiveRecord 查询(yii\db\ActiveQuery)。


1. 使用 indexBy() 方法

示例: 将用户列表的键设为 id 字段的值。

php

// 使用 Query Builder
$users = (new \yii\db\Query())
    ->select(['id', 'name', 'email'])
    ->from('user')
    ->indexBy('id')   // 指定索引字段
    ->all();

// 返回结果类似:
// [
//     1 => ['id' => 1, 'name' => 'Alice', 'email' => '...'],
//     2 => ['id' => 2, 'name' => 'Bob', 'email' => '...'],
// ]

ActiveRecord 示例:

php

// 使用 ActiveRecord
$users = User::find()
    ->select(['id', 'name', 'email'])
    ->indexBy('id')
    ->asArray()   // 可选,返回数组而非模型对象
    ->all();

如果不需要 asArray(),返回的是模型对象数组,键同样会按指定字段索引:

php

$users = User::find()->indexBy('id')->all();
// 结果: $users[1] 是 id=1 的用户模型对象

2. 使用 ArrayHelper::index() 对已有数组重新索引

如果你已经获取了结果集,可以使用 yii\helpers\ArrayHelper::index() 来重新索引:

php

use yii\helpers\ArrayHelper;

$users = User::find()->asArray()->all();
$indexedUsers = ArrayHelper::index($users, 'id');
// 结果键为 id 的值

3. 使用复杂表达式作为键

indexBy() 也可以接收一个回调函数,允许你使用组合字段或经过计算的字段作为键:

php

$users = User::find()
    ->indexBy(function ($row) {
        // $row 是数组或对象(取决于是否 asArray)
        return $row['id'] . '_' . $row['name'];
    })
    ->all();

注意事项

  • 唯一性:如果索引字段的值重复,后面的值会覆盖前面的值。
  • 性能indexBy() 是在 PHP 层面重新索引,对大数据集有一定内存开销,但通常可接受。
  • asArray() 配合:如果不需要模型对象,建议加上 asArray() 提高性能。

总结

场景推荐方法

查询时直接指定键

->indexBy('field')

已有结果集重新索引

ArrayHelper::index($data, 'field')

复杂键(组合或计算)

->indexBy(function(){...})

根据需要选择即可。