Skip to main content

什麼是模型事件

Eloquent 模型會在生命週期的各時機自動觸發事件。透過 hook 這些事件,可以在模型的儲存、刪除等前後插入處理。 Eloquent 所觸發的事件如下。 -ing 結尾的事件在變更寫入 DB 前觸發,以 -ed 結尾則是寫入後觸發。
批次更新或批次刪除(如 User::where(...)->update(...))不會觸發 savingsavedupdatingupdateddeletingdeleted 事件,因為模型實際上並未被取得。

使用 Closure 的事件監聽器

若想簡單處理事件,可於模型的 booted 方法中註冊 closure。
若希望以 Queue 非同步執行處理,可使用 queueable helper。

$dispatchesEvents 屬性

若要與 Laravel 的事件系統整合,可透過 $dispatchesEvents 屬性將模型事件對應至自訂事件類別。
對應的事件類別會在建構函式接收模型實例。

建立 Observer 類別

當要對單一模型處理多個事件時,比起列舉 closure,將其彙整為 Observer 類別更為簡潔。
1

以 Artisan 指令產生類別

make:observer 指令產生範本。加上 --model 選項指定模型,則會自動加入對應的方法。
會產生 app/Observers/UserObserver.php
2

實作各事件的方法

方法名稱對應事件名稱。引數會傳入模型實例。
3

於 Model 註冊 Observer

註冊方式有兩種。在 Laravel 13 中推薦使用 #[ObservedBy] attribute。方式 1:#[ObservedBy] attribute(推薦)僅需於模型類別加上 attribute 即可完成註冊,無需變更 AppServiceProvider
要註冊多個 Observer,可重複加 attribute 或以陣列傳入。
方式 2:於 AppServiceProvider 註冊AppServiceProviderboot 方法中呼叫 observe
#[ObservedBy] attribute 位於 Illuminate\Database\Eloquent\Attributes 命名空間。是 PHP 8.0 以後的原生語法,於 Laravel 13 積極被採用。

資料庫交易內的 Observer

當模型於交易內建立或更新時,有時希望在交易 commit 後才執行 Observer。可透過實作 ShouldHandleEventsAfterCommit 介面達成此行為。
若在交易外執行,則會如往常立即執行。

暫時停用事件

withoutEvents 僅為特定處理停止事件

於傳入 User::withoutEvents() 的 closure 中,所有模型事件都不會觸發。

saveQuietly 停止儲存時的事件

若希望在不觸發事件的情況下儲存模型,可使用 saveQuietly
刪除、復原、複製也提供了同樣的方法。

實務使用情境

快取的自動清除

當模型被更新或刪除時,自動清除相關的快取。

稽核日誌的記錄

自動記錄模型的變更歷史。可用 getDirty() 取得變更前後的值。
由於 updating 事件於 DB 儲存觸發,可以透過 getDirty() 取得預定變更的值。若於 updated 事件後呼叫,getDirty() 會變為空。

關聯模型的自動更新

以下為訂單完成時自動更新庫存數量的範例。

下一步

進階:PHP Attributes

一併學習包含 #[ObservedBy] 的 Laravel 13 PHP Attributes。
最後修改於 2026年8月2日