Skip to main content

什麼是 Macroable trait

Macroable trait 是可在不修改類別的情況下,事後動態新增方法的機制。Laravel 許多核心類別皆使用此 trait,因此可以在不修改核心程式碼的前提下擴充功能。 trait 的實體位於 Illuminate\Support\Traits\Macroable。內部將已註冊的 macro 儲存於靜態屬性 $macros,並透過 __call / __callStatic 魔術方法呼叫。

使用 Macroable 的類別

Laravel 中有許多支援 Macroable 的類別。

macro() — 新增方法

macro() 的第 1 個引數為方法名稱,第 2 個引數為 closure。
Closure 內的 $this 會被綁定至呼叫該 macro 的實例。因此可以直接存取類別的屬性或方法。

mixin() — 一次新增多個方法

若要一次註冊多個 macro,可使用 mixin()。Mixin 類別的 public / protected 方法都會被註冊為 macro。
mixin() 的方法必須回傳將被註冊為 macro 的 closure。方法自身的回傳值即為 macro 的實作。

於服務提供者註冊

Macro 需於應用程式啟動時註冊。AppServiceProviderboot() 方法為合適之處。

實務使用情境

擴充 Collection

為 Collection 新增自訂方法是最常見的使用案例。

擴充 Str 類別

擴充 Request 類別

擴充 Blueprint(Migration)

若將 Schema 的欄位定義集中 macro 化,可保持一致的 DB 設計。

擴充測試 Response

可新增測試專用的斷言方法。

hasMacro() — 檢查 macro 是否存在

flushMacros() — 重設 macro

於測試中希望重設 macro 時使用。
flushMacros() 會刪除該類別的所有 macro。為維持測試間的獨立性有時會於 tearDown() 呼叫,但也會使其他測試中註冊的 macro 消失,需注意。

靜態 macro

Macro 不僅能作為實例方法運作,也能作為靜態方法運作。由 __callStatic 處理。

於自訂類別使用 Macroable trait

也可以將 Macroable 組入自己的類別。

內部實作細節

Closure 透過 Closure::bindTo() 綁定至實例。如此 $this 便指向呼叫 macro 的物件。若為非 closure(如 invokable 物件),則不會被綁定。
若要獲得 IDE 支援,可以用 @mixin Doc Block 定義 macro 的註解,或使用 Laravel IdeHelper 套件自動生成 helper 檔案。

下一步

Pipeline 模式

學習如何使用 Pipeline 模式將多個處理步驟串聯組合。
最後修改於 2026年8月2日