概要
Eloquentモデルはインスタンス化のたびに「起動処理(boot)」と「初期化処理(initialize)」を実行します。トレイトにこれらのメソッドを定義しておくと、モデルがそのトレイトをuse するだけで自動的に呼び出されます。
この仕組みを使うことで、モデルに機能を注入するトレイトをクリーンに実装できます。Laravelフレームワーク自体も SoftDeletes などの多くのトレイトでこのパターンを活用しています。
boot と initialize の違い
ネーミング規約
bootXxx()
トレイト名の末尾にboot プレフィックスをつけた static メソッドを定義すると、モデル起動時に一度だけ呼ばれます。
initializeXxx()
トレイト名の末尾にinitialize プレフィックスをつけたインスタンスメソッドを定義すると、モデルの new のたびに呼ばれます。
$casts への動的な追加にも使えます:
PHP Attribute による明示的な指定
Laravel 12 以降、ネーミング規約に頼らず PHP Attribute で明示的にメソッドを指定できます。PHP Attribute を使うと、メソッド名がトレイト名に縛られないため、意味のある名前をつけられます。複数の
#[Boot] メソッドや #[Initialize] メソッドを同じトレイトに定義することも可能です。実用例:パッケージ開発での活用
グローバルスコープの自動追加
デフォルトキャスト追加
Eloquentイベントで自動処理
Laravelフレームワーク内の例
Laravelフレームワーク自身も多くのトレイトでこのパターンを採用しています。
これらを参考実装として読むと、パターンの理解が深まります。
注意点
モデルキャッシュのクリア
boot* はクラスごとに一度しか実行されないため、テスト環境では注意が必要です。Model::clearBootedModels() で起動済みキャッシュをリセットできます。
実行順序
同一モデルに複数のトレイトがuse されている場合、bootXxx() / initializeXxx() はPHPのトレイト解決順(宣言順)で呼ばれます。依存関係がある場合は use の順序に注意してください。
まとめ
トレイトに
bootXxx() / initializeXxx() を実装しておくと、モデルへの機能注入が use 一行で済むようになります。パッケージでモデルに機能を追加する際の定番パターンです。