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;23$users = User::where('active', 1)->get();45foreach ($users as $user) {6 echo $user->name;7}
1use App\Models\User;23$users = User::where('active', 1)->get();45foreach ($users as $user) {6 echo $user->name;7}
不過,剛才也提到過,Collection 比起陣列來說多了很多更強大的功能。而且,Collection 也提供了多種可通過直觀介面串連使用的各個 map / reduce 操作。舉例來說,我們可以將所有非啟用狀態的 Model 移除,並取得剩餘使用者的名字:
1$names = User::all()->reject(function ($user) {2 return $user->active === false;3})->map(function ($user) {4 return $user->name;5});
1$names = User::all()->reject(function ($user) {2 return $user->active === false;3})->map(function ($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
實體。
contains diff except find fresh intersect load loadMissing modelKeys makeVisible makeHidden only toQuery unique
contains($key, $operator = null, $value = null)
contains
方法可用來判斷給定的 Model 實體是否包含在該 Collection 內。該方法可接受主鍵 (Primary Key) 或 Model 實體:
1$users->contains(1);23$users->contains(User::find(1));
1$users->contains(1);23$users->contains(User::find(1));
diff($items)
diff
方法會回傳所有不存在給定 Collection 中的所有 Model:
1use App\Models\User;23$users = $users->diff(User::whereIn('id', [1, 2, 3])->get());
1use App\Models\User;23$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();23$user = $users->find(1);
1$users = User::all();23$user = $users->find(1);
fresh($with = [])
fresh
方法會從資料庫中取得該 Collection 中各個 Model 的最新實體 (Fresh Instance)。此外,若有指定關聯,則會積極式載入 (Eager Loading) 這些關聯:
1$users = $users->fresh();23$users = $users->fresh('comments');
1$users = $users->fresh();23$users = $users->fresh('comments');
intersect($items)
diff
方法會回傳所有同時存在於給定 Collection 中的所有 Model:
1use App\Models\User;23$users = $users->intersect(User::whereIn('id', [1, 2, 3])->get());
1use App\Models\User;23$users = $users->intersect(User::whereIn('id', [1, 2, 3])->get());
load($relations)
load
方法會積極式載入 (Eager Loading) Collection 中所有 Model 上的給定關聯:
1$users->load(['comments', 'posts']);23$users->load('comments.author');
1$users->load(['comments', 'posts']);23$users->load('comments.author');
loadMissing($relations)
loadMissing
方法會在該 Collection 中所有 Model 的給定關聯尚未載入時將其積極式載入 (Eager Loading):
1$users->loadMissing(['comments', 'posts']);23$users->loadMissing('comments.author');
1$users->loadMissing(['comments', 'posts']);23$users->loadMissing('comments.author');
modelKeys()
modelKeys
方法會回傳該 Collection 中所有方法的主鍵:
1$users->modelKeys();23// [1, 2, 3, 4, 5]
1$users->modelKeys();23// [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]);
toQuery()
toQuery
方法回傳 Eloquent Query Builder 實體,並包含了由該 Collection 中 Model 的主索引鍵所組成的 whereIn
限制式:
1use App\Models\User;23$users = User::where('status', 'VIP')->get();45$users->toQuery()->update([6 'status' => 'Administrator',7]);
1use App\Models\User;23$users = User::where('status', 'VIP')->get();45$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<?php23namespace App\Models;45use App\Support\UserCollection;6use Illuminate\Database\Eloquent\Model;78class User extends Model9{10 /**11 * Create a new Eloquent Collection instance.12 *13 * @param array $models14 * @return \Illuminate\Database\Eloquent\Collection15 */16 public function newCollection(array $models = [])17 {18 return new UserCollection($models);19 }20}
1<?php23namespace App\Models;45use App\Support\UserCollection;6use Illuminate\Database\Eloquent\Model;78class User extends Model9{10 /**11 * Create a new Eloquent Collection instance.12 *13 * @param array $models14 * @return \Illuminate\Database\Eloquent\Collection15 */16 public function newCollection(array $models = [])17 {18 return new UserCollection($models);19 }20}
定義好 newCollection
方法後,之後,在 Eloquent 通常會回傳 Illuminate\Database\Eloquent\Collection
實體的時候,就會變成你的自訂 Collection 實體。若想在專案中的所有 Model 上都使用某個自訂 Collection,則可在一個基礎 Model 類別上定義 newCollection
方法,並讓專案內所有的 Model 都繼承該基礎 Model: