Eloquent:Collection

簡介

Eloquent 中,所有回傳多筆 Model 結果的方法都會回傳 Illuminate\Database\Eloquent\Collection 的實體,這些方法包含 get 方法或是以關聯進行存取時。Eloquent Collection 物件繼承自 Laravel 的基礎 Collection,因此,這些 Collection 也自然繼承了數十種可用來流暢地操作底層 Eloquent Model 陣列的方法。記得看看 Laravel Collection 說明文件來了解這些實用的方法!

所有的 Collection 也可作為迭代器使用,因此你可以很輕鬆地像迭代一般 PHP 陣列一樣迭代這些 Collection:

1use App\Models\User;
2 
3$users = User::where('active', 1)->get();
4 
5foreach ($users as $user) {
6 echo $user->name;
7}
1use App\Models\User;
2 
3$users = User::where('active', 1)->get();
4 
5foreach ($users as $user) {
6 echo $user->name;
7}

不過,剛才也提到過,Collection 比起陣列來說多了很多更強大的功能。而且,Collection 也提供了多種可通過直觀介面串連使用的各個 map / reduce 操作。舉例來說,我們可以將所有非啟用狀態的 Model 移除,並取得剩餘使用者的名字:

1$names = User::all()->reject(function (User $user) {
2 return $user->active === false;
3})->map(function (User $user) {
4 return $user->name;
5});
1$names = User::all()->reject(function (User $user) {
2 return $user->active === false;
3})->map(function (User $user) {
4 return $user->name;
5});

Eloquent Collection 轉換

雖然大多數的 Eloquent Collection 方法都會回傳新的 Eloquent Collection 實體,但 collapse, flatten, flip, keys, pluck, 與 zip 方法都會回傳基礎 collection實體。同樣地,若 map 操作回傳不包含任何 Eloquent Model 的實體,則會回傳基礎 Collection 實體。

可用方法

所有的 Eloquent Collection 都繼承自基礎 Laravel Collection 物件。因此,這些 Collection 都繼承了基礎 Collection 類別所提供的所有強大方法。

除此之外,Illuminate\Database\Eloquent\Collection 類別還提供了一組可用來處理 Model Collection 的方法。大多數的方法都會回傳 Illuminate\Database\Eloquent\Collection 實體。不過,有些如 modelKeys 之類的方法則會回傳 Illuminate\Support\Collection 實體。

append($attributes)

append 方法可用來表示某個屬性應被附加到該 Collection 中的每個 Model 上。可傳入一組屬性陣列或單一屬性給該方法:

1$users->append('team');
2 
3$users->append(['team', 'is_admin']);
1$users->append('team');
2 
3$users->append(['team', 'is_admin']);

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

contains 方法可用來判斷給定的 Model 實體是否包含在該 Collection 內。該方法可接受主鍵 (Primary Key) 或 Model 實體:

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

diff($items)

diff 方法會回傳所有不存在給定 Collection 中的所有 Model:

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

except($keys)

except 方法會回傳沒有給定主鍵的所有 Model:

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

find($key)

find 方法會回傳主鍵符合給定索引鍵的 Model。若 $key 為 Model 實體,則 find 會嘗試回傳符合該主鍵的 Model。若 $key 為一組索引鍵的陣列,則 find 會回傳所有主鍵包含在給定陣列中的 Model:

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

fresh($with = [])

fresh 方法會從資料庫中取得該 Collection 中各個 Model 的最新實體 (Fresh Instance)。此外,若有指定關聯,則會積極式載入 (Eager Loading) 這些關聯:

1$users = $users->fresh();
2 
3$users = $users->fresh('comments');
1$users = $users->fresh();
2 
3$users = $users->fresh('comments');

intersect($items)

diff 方法會回傳所有同時存在於給定 Collection 中的所有 Model:

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

load($relations)

load 方法會積極式載入 (Eager Loading) Collection 中所有 Model 上的給定關聯:

1$users->load(['comments', 'posts']);
2 
3$users->load('comments.author');
4 
5$users->load(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);
1$users->load(['comments', 'posts']);
2 
3$users->load('comments.author');
4 
5$users->load(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);

loadMissing($relations)

loadMissing 方法會在該 Collection 中所有 Model 的給定關聯尚未載入時將其積極式載入 (Eager Loading):

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

modelKeys()

modelKeys 方法會回傳該 Collection 中所有方法的主鍵:

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

makeVisible($attributes)

makeVisible 方法會將該 Collection 中所有 Model 上通常「隱藏 (Hidden)」的屬性設為可見

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

makeHidden($attributes)

makeHidden 方法會將該 Collection 中所有 Model 上通常「可見 (Visible)」的屬性設為隱藏

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

only($keys)

except 方法會回傳符合給定主鍵的所有 Model:

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

setVisible($attributes)

setVisible 方法可暫時複寫掉該 Collection 中各個 Model 的所有 visible(可見) 屬性:

1$users = $users->setVisible(['id', 'name']);
1$users = $users->setVisible(['id', 'name']);

setHidden($attributes)

setHidden 方法可暫時複寫掉該 Collection 中各個 Model 的所有 hidden(隱藏) 屬性:

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

toQuery()

toQuery 方法回傳 Eloquent Query Builder 實體,並包含了由該 Collection 中 Model 的主索引鍵所組成的 whereIn 限制式:

1use App\Models\User;
2 
3$users = User::where('status', 'VIP')->get();
4 
5$users->toQuery()->update([
6 'status' => 'Administrator',
7]);
1use App\Models\User;
2 
3$users = User::where('status', 'VIP')->get();
4 
5$users->toQuery()->update([
6 'status' => 'Administrator',
7]);

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

unique 方法會回傳該 Collection 中所有不重複的 Model。只要某個 Model 在該 Collection 中有另一個具有相同型別與相同主鍵的 Model,就會被移除:

1$users = $users->unique();
1$users = $users->unique();

自訂 Collection

若想在與給定 Model 互動時使用自訂 Collection 實體,可在 Model 中定義一個 newCollection 方法:

1<?php
2 
3namespace App\Models;
4 
5use App\Support\UserCollection;
6use Illuminate\Database\Eloquent\Collection;
7use Illuminate\Database\Eloquent\Model;
8 
9class User extends Model
10{
11 /**
12 * Create a new Eloquent Collection instance.
13 *
14 * @param array<int, \Illuminate\Database\Eloquent\Model> $models
15 * @return \Illuminate\Database\Eloquent\Collection<int, \Illuminate\Database\Eloquent\Model>
16 */
17 public function newCollection(array $models = []): Collection
18 {
19 return new UserCollection($models);
20 }
21}
1<?php
2 
3namespace App\Models;
4 
5use App\Support\UserCollection;
6use Illuminate\Database\Eloquent\Collection;
7use Illuminate\Database\Eloquent\Model;
8 
9class User extends Model
10{
11 /**
12 * Create a new Eloquent Collection instance.
13 *
14 * @param array<int, \Illuminate\Database\Eloquent\Model> $models
15 * @return \Illuminate\Database\Eloquent\Collection<int, \Illuminate\Database\Eloquent\Model>
16 */
17 public function newCollection(array $models = []): Collection
18 {
19 return new UserCollection($models);
20 }
21}

定義好 newCollection 方法後,之後,在 Eloquent 通常會回傳 Illuminate\Database\Eloquent\Collection 實體的時候,就會變成你的自訂 Collection 實體。若想在專案中的所有 Model 上都使用某個自訂 Collection,則可在一個基礎 Model 類別上定義 newCollection 方法,並讓專案內所有的 Model 都繼承該基礎 Model:

翻譯進度
100% 已翻譯
更新時間:
2023年2月11日 上午10:27:00 [世界標準時間]
翻譯人員:
  • cornch
幫我們翻譯此頁

留言

尚無留言

“Laravel” is a Trademark of Taylor Otwell.
The source documentation is released under MIT license. See laravel/docs on GitHub for details.
The translated documentations are released under MIT license. See cornch/laravel-docs-l10n on GitHub for details.