概觀
Eloquent 模型每次實例化時都會執行「啟動處理(boot)」與「初始化處理(initialize)」。若在 trait 中定義了這些方法,只要模型use 該 trait,便會自動被呼叫。
透過此機制,可以乾淨地實作向模型注入功能的 trait。Laravel 框架本身也在 SoftDeletes 等許多 trait 中活用此模式。
boot 與 initialize 的差異
命名慣例
bootXxx()
在 trait 名稱前加上boot 前綴的 static 方法,會於模型啟動時被呼叫一次。
initializeXxx()
在 trait 名稱前加上initialize 前綴的實例方法,會於模型每次 new 時被呼叫。
$casts:
以 PHP Attribute 明確指定
Laravel 12 以後,可不依賴命名慣例,透過 PHP Attribute 明確指定方法。使用 PHP Attribute 時,方法名稱不再受限於 trait 名稱,可取具意義的名稱。也可於同一 trait 中定義多個
#[Boot] 或 #[Initialize] 方法。實務範例:套件開發的活用
自動新增 Global Scope
加入預設 cast
以 Eloquent 事件自動處理
Laravel 框架內的範例
Laravel 框架本身也在許多 trait 中採用此模式。
以這些作為參考實作閱讀,能加深對此模式的理解。
注意事項
模型快取的清除
由於boot* 每個類別只執行一次,在測試環境中需要留意。可透過 Model::clearBootedModels() 重置已啟動的快取。
執行順序
若同一模型use 了多個 trait,bootXxx() / initializeXxx() 會依 PHP 的 trait 解析順序(宣告順序)呼叫。若有依賴關係,請留意 use 的順序。
總結
於 trait 中實作
bootXxx() / initializeXxx(),讓向模型注入功能只需 use 一行即可完成。這是套件為模型新增功能時的常見模式。