在使用 Eloquent 模型時,通常會利用通過模型生命週期調度的事件。有幾種不同的方法可以做到這一點,在本教程中,我將介紹它們並解釋每種方法的優缺點。 【相關推薦:laravel影片教學】
我將為每種方法使用相同的範例,以便你可以直接進行比較。此範例將在建立模型本身的過程中將模型的 UUID 屬性指派給 UUID 。
我們的第一種方法使用模型的靜態引導方法來註冊行為。這使我們能夠直接在模型上工作,並在模型為 created 。
declare(strict_types=1); namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Office extends Model { public static function boot(): void { static::creating(fn (Model $model) => $model->uuid = Str::uuid(), ); } }
這種方法非常適合對模型事件的小而直接的反應,例如添加 UUID ,因為它非常容易理解,而且你可以準確地看到模型上正在發生的事情。這種方法最大的問題是程式碼重複,如果你有多個模型需要分配 UUID ,你會重複做同樣的事情。
這很好地引導我們進入第二種方法,使用一個特徵。在 Laravel 中,如果你在 trait 上建立一個以 boot
開頭並以 trait 名稱結尾的方法,你的模型可以繼承 trait 並自動啟動它們。這是一個例子:
declare(strict_types=1); namespace App\Models\Concerns; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; trait HasUuid { public static function bootHasUuid(): void { static::creating(fn (Model $model) => $model->uuid = Str::uuid(), ); } }
使用特徵允許你將此行為添加到需要它且易於實現的每個模型中。我最大的缺點是,當多個特徵想要利用同一個模型事件時,堆疊這些行為可能會導致問題。他們開始爭奪優先權,很快就會變得一團糟。
這將我們引向下一個選項,模型觀察者。模型觀察者是一種基於類別的方法來回應模型事件,其中方法對應於被觸發的特定事件。
declare(strict_types=1); namespace App\Observers; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class OfficeObserver { public function creating(Model $model): void { $model->uuid = Str::uuid(); } }
這個類別需要在某個地方註冊,在服務提供者或模型本身(這是我推薦的地方)。在模型中註冊這個觀察者可以在模型層級上看到改變雄辯行為的副作用。將其隱藏在服務提供者中的問題在於,除非每個人都知道它的存在,否則很難知道。這種方法的最大缺點是它的可見性。在我看來,正確使用這種方法非常棒。
解決此問題的另一種方法是利用 Eloquent 模型本身的$dispatchesEvents
屬性。這是每個 Eloquent 模型上的一個屬性,它允許你列出要偵聽的事件以及為這些事件呼叫的類別。
declare(strict_types=1); namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Office extends Model { protected $dispatchesEvents = [ 'creating' => SetModelUuid::class, ]; }
SetModelUuid
將在 Eloquent 模型的生命週期中被實例化,這是你向模型添加行為和屬性的機會。
declare(strict_types=1); namespace App\Models\Events; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class SetModelUuid { public function __construct(Model $model) { $model->uuid = Str::uuid(); } }
這種方法是最簡潔和最容易理解的方法之一,因為模型有很多可見性,並且你可以輕鬆地在模型之間共享這個類別。你將面臨的最大問題是是否需要在模型事件上觸發多個操作。
總之,老實說,沒有正確的方法可以做到這一點。你可以選擇上述任何一種方法,它們都會起作用,但你應該選擇適合你和你的特定用例的方法。我希望看到有關此特定功能的更多選項。
例如,如果你需要在模型事件上為模型新增多個屬性,則觀察者是一個不錯的選擇。然而,這是最好的選擇嗎?如果我們使用 dispatch events 屬性為該模型運行自訂管道會怎樣?
declare(strict_types=1); namespace App\Models\Pipelines; use App\Models\Office class OfficeCreatingPipeline { public function __construct(Office $model) { app(Pipeline::class) ->send($model) ->through([ ApplyUuidProperty::class, TapCreatedBy::class, ]); } }
如你所見,我們可以開始使用管道來為事件建模添加多個行為。現在,這還沒有經過測試,所以我不知道 100% 是否可行 - 但作為一個概念,它可以開闢一種可組合的方法來對模型事件做出反應。
你如何處理 Laravel 專案中的模型事件?在推特上告訴我們!
原文網址:https://laravel-news.com/working-with-laravel-model-events
翻譯網址:https://learnku.com/laravel/ t/71183
更多程式相關知識,請造訪:程式設計影片! !
以上是聊聊Laravel中模型事件怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!