什麼是 Higher Order Messages
Higher-order Messages 是以屬性存取形式呼叫 Collection 方法的語法。無需撰寫 callback,就能對每個元素呼叫方法或取得屬性。$users->map->name 的意義是「取出每個 user 的 name 屬性再 map」。
機制 — HigherOrderCollectionProxy
若像$collection->map 一樣以屬性存取,EnumeratesValues trait 的 __get() 會被呼叫。
$proxies 中,會回傳 HigherOrderCollectionProxy 實例。此 proxy 保存 collection 與方法名稱兩者。
透過 __get 的屬性存取代理
接著若存取屬性(->name),會呼叫 proxy 的 __get()。
$users->map->name 等同於:
透過 __call 的方法呼叫代理
接著若呼叫方法(->activate()),會呼叫 proxy 的 __call()。
$users->each->activate() 等同於:
支援的方法列表
可作為 Higher Order Messages 使用的方法定義於$proxies 陣列。
Collection::proxy()。
實務使用情境
Eloquent Model 的 Collection
Higher Order Messages 在 Eloquent 的 Collection 中特別便利。篩選
彙總
分組、排序
以 flatMap 展開巢狀
條件確認
字串 Collection
值為字串的 collection 也可以使用。proxy 的__call() 於字串時會以靜態方法呼叫。
對字串 collection 使用 Higher Order Messages 時,方法必須以靜態方式定義於字串型別上。通常較自然的用法是搭配 Eloquent 模型或自訂類別的 collection。
與一般 closure 的比較
Higher Order Messages 雖然簡潔,但並非所有情境皆適用。於自訂類別使用 Higher Order Messages
要透過EnumeratesValues trait 利用 HigherOrderCollectionProxy 機制,可呼叫 Collection::proxy() 將方法加入 proxy 對象。
下一步
Conditionable trait
學習
when() / unless() 的內部實作,以及套用於 QueryBuilder 及自訂類別的方法。