什麼是 ForwardsCalls trait
Illuminate\Support\Traits\ForwardsCalls 是將對某物件的方法委派共同化的 trait。Laravel 本體中,Eloquent 或 Mail 等「wrapper 物件」皆會使用。
實作位於
src/Illuminate/Support/Traits/ForwardsCalls.php。轉發不存在的方法時,會將包含呼叫端類別名稱的 BadMethodCallException 重新拋出。Core API
forwardCallTo($object, $method, $parameters)
將方法原封不動轉發至指定物件。典型上會由 __call() 呼叫。
forwardDecoratedCallTo($object, $method, $parameters)
用於在 Builder 或 Decorator 中維持鏈式呼叫。若轉發目標方法的回傳值為「轉發目標物件本身」,則會替換為「呼叫端物件($this)」回傳。
與 __call() / __callStatic() 的組合
ForwardsCalls 本身不提供魔術方法。應由您的類別實作 __call()(必要時 __callStatic()),並在其中呼叫 forwardCallTo 系列方法。
實際使用範例(Laravel 內部)
1
Facade 提供 static proxy
Illuminate\Support\Facades\Facade 以 __callStatic() 直接委派給 root instance。Facade 由於是 static 呼叫,實作上是直接轉發而非使用 ForwardsCalls。2
Eloquent Builder 使用 forwardCallTo
Illuminate\Database\Eloquent\Builder::__call() 將未解析的方法以 forwardCallTo($this->query, ...) 傳給內部 Query Builder,最後回傳 $this 以維持 fluent chain。3
Relation / Mail / Event 使用 forwardDecoratedCallTo
在
Illuminate\Database\Eloquent\Relations\Relation、Illuminate\Mail\Message、Illuminate\Events\NullDispatcher 中會使用 forwardDecoratedCallTo,在委派給內部物件的同時保持外側 API 的鏈式呼叫。基本 Proxy 實作(forwardCallTo)
CourierProxy 即可透明地暴露 CourierDriver 的 public API。
支援方法鏈的 Proxy(forwardDecoratedCallTo)
自動拋出 BadMethodCallException
若呼叫不存在的方法,ForwardsCalls 會以呼叫端類別名稱重新拋出 BadMethodCallException。
與 Macroable 的比較
套件開發的活用範例
1)可切換 Driver 的 Manager
2)具有多後端的 Adapter
HTTP / Queue / WebSocket 等不同後端可以統一於一個 API 進行委派。3)測試用 Spy / Stub
以 Spy 取代實際 Driver 注入,呼叫透過forwardCallTo 直接流過,藉此驗證呼叫次數與引數。
相關頁面
Macroable trait
學習為既有類別加入新方法的擴充模式。
Conditionable trait
學習透過
when() / unless() 進行條件分支鏈的設計。