跳转到主要内容

简介

在 Eloquent 中获取多条模型时,结果会以 Illuminate\Database\Eloquent\Collection 的形式返回。 它继承自 Illuminate\Support\Collection,因此可以直接使用基础集合的所有方法。
use App\Models\User;

$users = User::where('active', true)->get();

foreach ($users as $user) {
    echo $user->name;
}
先掌握基础的集合Eloquent 入门,会更容易理解 Eloquent 集合的扩展点。

可用方法

Eloquent\Collection 继承了基础集合的所有方法,并进一步为模型场景增加了新方法。

append / withoutAppends / setAppends

对整个集合操作序列化时的追加属性(appends)。
$users->append('team');
$users->append(['team', 'is_admin']);

$users = $users->withoutAppends();
$users = $users->setAppends(['is_admin']);

contains / diff / except / intersect / only

基于模型实例或主键,进行包含判定、差集、交集、排除以及提取。
use App\Models\User;

$users->contains(1);
$users->contains(User::find(1));

$subset = User::whereIn('id', [1, 2, 3])->get();

$users->diff($subset);
$users->intersect($subset);

$users->except([1, 2, 3]);
$users->only([1, 2, 3]);

find / findOrFail

从已取得的集合中按主键查找模型。
$users = User::all();

$user = $users->find(1);
$user = $users->findOrFail(1);

fresh

以数据库中的最新状态重新获取集合中的每个模型。
$users = $users->fresh();
$users = $users->fresh('comments');

load / loadMissing

对已取得的集合,稍后进行关联的预加载(Eager Loading)。
$users->load(['comments', 'posts']);
$users->load('comments.author');
$users->load(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);

$users->loadMissing(['comments', 'posts']);
$users->loadMissing('comments.author');
$users->loadMissing(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);

modelKeys

获取集合内模型的主键列表。
$users->modelKeys();
// [1, 2, 3, ...]

makeVisible / makeHidden / mergeVisible / mergeHidden / setVisible / setHidden

以集合为单位调整序列化时的可见属性与不可见属性。
$users = $users->makeVisible(['address', 'phone_number']);
$users = $users->makeHidden(['address', 'phone_number']);

$users = $users->mergeVisible(['middle_name']);
$users = $users->mergeHidden(['last_login_at']);

$users = $users->setVisible(['id', 'name']);
$users = $users->setHidden(['email', 'password', 'remember_token']);

partition

按条件把集合拆分成两个 Eloquent\Collection,外层则返回一个 Illuminate\Support\Collection
$partition = $users->partition(fn ($user) => $user->age > 18);

dump($partition::class);    // Illuminate\Support\Collection
dump($partition[0]::class); // Illuminate\Database\Eloquent\Collection
dump($partition[1]::class); // Illuminate\Database\Eloquent\Collection

toQuery

基于已取得模型集合的主键构建 whereIn 查询,可用于批量更新或删除。
use App\Models\User;

// 首先取出满足条件的用户
$vipUsers = User::where('status', 'VIP')->get();

// 只对集合内的对象进行批量更新
$vipUsers->toQuery()->update([
    'status' => 'Administrator',
]);
相比在循环里逐个 save(),使用 toQuery() 转换为批量查询,能在实际运维中兼顾性能与可读性。

unique

移除具有相同主键的重复模型。
$users = $users->unique();

从 Eloquent 集合转换为基础集合

collapseflattenflipkeyspluckzip 会返回 Illuminate\Support\Collection。 另外,当 map 的结果中不包含 Eloquent 模型时,也会被转换为基础集合。

自定义集合

如果你希望使用模型专属的集合类,最清晰的方式是先使用 #[CollectedBy] 属性。

#[CollectedBy] 属性(推荐)

<?php

namespace App\Models;

use App\Support\UserCollection;
use Illuminate\Database\Eloquent\Attributes\CollectedBy;
use Illuminate\Database\Eloquent\Model;

#[CollectedBy(UserCollection::class)]
class User extends Model
{
    // ...
}

newCollection() 方法(替代方式)

<?php

namespace App\Models;

use App\Support\UserCollection;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function newCollection(array $models = []): Collection
    {
        $collection = new UserCollection($models);

        if (Model::isAutomaticallyEagerLoadingRelationships()) {
            $collection->withRelationshipAutoloading();
        }

        return $collection;
    }
}
只要定义了 newCollection()#[CollectedBy],通常会返回 Eloquent\Collection 的场景就会改为返回自定义集合。 如果想对所有模型都生效,可以在共同的基础模型中定义 newCollection()

相关页面

集合

先确认 Illuminate\Support\Collection 的基本操作。

Eloquent 入门

梳理好模型与查询的基础后再来使用 Eloquent 集合。
最后修改于 2026年7月13日