Skip to main content

Macroableトレイトとは

Macroable トレイトは、クラスを変更せずに後からメソッドを動的に追加できる仕組みです。Laravelのコアクラスの多くがこのトレイトを使っているため、コアコードに手を加えることなく機能を拡張できます。 トレイトの実体は Illuminate\Support\Traits\Macroable にあります。内部的には、登録されたマクロを静的プロパティ $macros に格納し、__call / __callStatic マジックメソッドを通じて呼び出します。

Macroableを使っているクラス

Laravelには多くのMacroable対応クラスがあります。

macro() — メソッドを追加する

macro() の第一引数にメソッド名、第二引数にクロージャを渡します。
クロージャ内の $this はマクロを呼び出したインスタンスにバインドされます。これにより、クラスのプロパティやメソッドに直接アクセスできます。

mixin() — 複数メソッドをまとめて追加する

多くのマクロをまとめて登録したい場合は mixin() を使います。ミックスインクラスの public / protected メソッドがすべてマクロとして登録されます。
mixin() のメソッドは、マクロとして登録されるクロージャを返す必要があります。メソッド自体の戻り値がマクロの実装になります。

サービスプロバイダーへの登録

マクロはアプリケーション起動時に登録する必要があります。AppServiceProviderboot() メソッドが適切な場所です。

実践的なユースケース

コレクションの拡張

コレクションへのカスタムメソッド追加は最も一般的な使用例です。

Strクラスの拡張

Requestクラスの拡張

Blueprintの拡張(マイグレーション)

スキーマのカラム定義をまとめてマクロ化すると、一貫したDB設計を保てます。

テストレスポンスの拡張

テスト専用のアサーションメソッドを追加できます。

hasMacro() — マクロの存在確認

flushMacros() — マクロのリセット

テストでマクロをリセットしたい場合に使います。
flushMacros() はそのクラスのすべてのマクロを削除します。テスト間の独立性を保つために tearDown() で呼ぶことがありますが、他のテストで登録したマクロも消えるため注意が必要です。

静的マクロ

マクロはインスタンスメソッドとしてだけでなく、静的メソッドとしても動作します。__callStatic によって処理されます。

Macroableトレイトを自作クラスで使う

自分で作ったクラスにも Macroable を組み込めます。

内部実装の詳細

クロージャは Closure::bindTo() によってインスタンスにバインドされます。これにより $this がマクロ呼び出し元のオブジェクトを指すようになります。クロージャ以外(invokableオブジェクトなど)の場合はバインドされません。
IDEのサポートを得るには、マクロのアノテーションを @mixin を使ったDocブロックで定義するか、Laravel IdeHelperパッケージを使ってヘルパーファイルを自動生成する方法があります。

次のステップ

Pipelineパターン

パイプラインパターンを使って複数の処理ステップを直列に構成する方法を学びます。
最終更新日 2026年3月27日