Macroableトレイトとは
Macroable トレイトは、クラスを変更せずに後からメソッドを動的に追加できる仕組みです。Laravelのコアクラスの多くがこのトレイトを使っているため、コアコードに手を加えることなく機能を拡張できます。
トレイトの実体は Illuminate\Support\Traits\Macroable にあります。内部的には、登録されたマクロを静的プロパティ $macros に格納し、__call / __callStatic マジックメソッドを通じて呼び出します。
Macroableを使っているクラス
Laravelには多くのMacroable対応クラスがあります。macro() — メソッドを追加する
macro() の第一引数にメソッド名、第二引数にクロージャを渡します。
$this はマクロを呼び出したインスタンスにバインドされます。これにより、クラスのプロパティやメソッドに直接アクセスできます。
mixin() — 複数メソッドをまとめて追加する
多くのマクロをまとめて登録したい場合はmixin() を使います。ミックスインクラスの public / protected メソッドがすべてマクロとして登録されます。
mixin() のメソッドは、マクロとして登録されるクロージャを返す必要があります。メソッド自体の戻り値がマクロの実装になります。サービスプロバイダーへの登録
マクロはアプリケーション起動時に登録する必要があります。AppServiceProvider の boot() メソッドが適切な場所です。
実践的なユースケース
コレクションの拡張
コレクションへのカスタムメソッド追加は最も一般的な使用例です。Strクラスの拡張
Requestクラスの拡張
Blueprintの拡張(マイグレーション)
スキーマのカラム定義をまとめてマクロ化すると、一貫したDB設計を保てます。テストレスポンスの拡張
テスト専用のアサーションメソッドを追加できます。hasMacro() — マクロの存在確認
flushMacros() — マクロのリセット
テストでマクロをリセットしたい場合に使います。静的マクロ
マクロはインスタンスメソッドとしてだけでなく、静的メソッドとしても動作します。__callStatic によって処理されます。
Macroableトレイトを自作クラスで使う
自分で作ったクラスにもMacroable を組み込めます。
内部実装の詳細
Closure::bindTo() によってインスタンスにバインドされます。これにより $this がマクロ呼び出し元のオブジェクトを指すようになります。クロージャ以外(invokableオブジェクトなど)の場合はバインドされません。
次のステップ
Pipelineパターン
パイプラインパターンを使って複数の処理ステップを直列に構成する方法を学びます。