集合


简介

Eloquent 返回的包含多条记录的结果集都是 Illuminate\Database\Eloquent\Collection 对象的实例,包括通过 get 方法或者通过访问关联关系获取的结果。Eloquent 集合对象继承自 Laravel 的集合基类,因此很自然的继承了很多处理 Eloquent 模型底层数组的方法。

当然,集合也是迭代器,允许你像 PHP 数组一样对其进行循环:

$users = App\User::where('active', 1)->get();
    
foreach ($users as $user) {
    echo $user->name;
}

不过,集合使用直观的接口提供了各种映射/简化操作,因此比数组更加强大。例如,我们可以通过以下方式移除所有无效的模型并聚合剩下用户的姓名:

$users = App\User::where('active', 1)->get();
    
$names = $users->reject(function ($user) {
    return $user->active === false;
})->map(function ($user) {
    return $user->name;
});

注:尽管大多数 Eloquent 集合返回的是一个新的 Eloquent 集合实例,但是pluckkeyszipcollapseflattenflip 方法返回的是集合基类实例。类似地,如果 map 操作返回的集合不包含任何 Eloquent 模型,将会被自动转化成集合基类。

可用方法

所有的 Eloquent 集合继承自 Laravel 集合对象基类,因此,它们继承所有集合基类提供的强大方法:集合方法大全

此外,Illuminate\Database\Eloquent\Collection 类还提供了一些方法超集以便帮助我们管理模型集合。这些方法大多返回 Illuminate\Database\Eloquent\Collection 实例,不过,有些也会返回 Illuminate\Support\Collection 实例:

contains($key, $operator = null, $value = null)

contains 方法可用于判断给定模型实例是否包含在集合中,该方法接收主键 ID 或模型实例作为参数:

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

diff($items)

diff 方法返回给定集合中所有不存在的模型:

use App\User;
    
$users = $users->diff(User::whereIn('id', [1, 2, 3])->get());

except($keys)

except 方法返回所有不包含给定主键的模型:

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

find($key)

find 方法会查找包含给定主键的模型。如果 $key 是一个模型实例,则 find 会尝试返回与该主键相匹配的模型;如果 $key 是一个主键数组,find 将会使用 whereIn() 返回与 keys 匹配的所有模型:

$users = User::all();
    
$user = $users->find(1);

findMany

findMany 方法通过传入主键数组返回所有模型:

$users = User::all();

$user = $users->findMany([1, 2, 3]);

fresh($with = [])

fresh 方法会从数据库中获取集合中每个模型的新实例,此外,任何指定的关联关系都会被渴求式加载:

$users = $users->fresh();
    
$users = $users->fresh('comments');

intersect($items)

intersect 方法返回所有同时存在于给定集合的模型:

use App\User;
    
$users = $users->intersect(User::whereIn('id', [1, 2, 3])->get());

load($relations)

load 方法会渴求式加载集合中所有模型的给定关联关系:

$users->load('comments', 'posts');
    
$users->load('comments.author');

loadMissing($relations)

loadMissing 方法会渴求式加载集合中所有模型的给定关联关系,如果这个关联关系还没有被加载的话:

$users->loadMissing('comments', 'posts');
    
$users->loadMissing('comments.author');

modelKeys()

modelKeys 方法会返回集合中所有模型的主键:

$users->modelKeys();
    
// [1, 2, 3, 4, 5]

makeVisible($attributes)

makeVisible 方法会让集合中每个模型的「hidden」属性变成可见:

$users = $users->makeVisible(['address', 'phone_number']);

makeHidden($attributes)

makeHidden 方法会让集合中每个模型的「visible」属性隐藏起来:

$users = $users->makeHidden(['address', 'phone_number']);

only($keys)

only 方法会返回包含给定主键的所有模型:

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

unique($key = null, $strict = false)

unique 方法会返回集合中的所有唯一模型,即剔除重复模型,任何类型相同主键相同的重复模型都会被移除:

$users = $users->unique();

自定义集合

如果你需要在自己扩展的方法中使用自定义的集合对象,可以重写模型上的 newCollection 方法:

<?php
    
namespace App;
    
use App\CustomCollection;
use Illuminate\Database\Eloquent\Model;
    
class User extends Model
{
    /**
     * 创建一个新的Eloquent集合实例
     *
     * @param  array  $models
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function newCollection(array $models = [])
    {
        return new CustomCollection($models);
    }
}

定义好 newCollection 方法后,无论何时 Eloquent 返回该模型的 Collection 实例你都会获取到自定义的集合。如果你想要在应用中的每一个模型中使用自定义集合,需要在模型基类中重写 newCollection 方法。


点赞 取消点赞 收藏 取消收藏

<< 上一篇: 关联关系

>> 下一篇: 访问器和修改器