跳转到主要内容

什么是模型事件

Eloquent 模型会在生命周期的各时点自动触发事件。通过挂钩这些事件,可以在模型保存、删除等操作的前后插入自定义处理。 Eloquent 触发的事件如下。 -ing 结尾的事件在变更持久化到 DB 之前触发,以 -ed 结尾的则在之后触发。
批量更新与批量删除(如 User::where(...)->update(...))不会触发 savingsavedupdatingupdateddeletingdeleted 事件,因为模型并未真正被实例化。

用闭包注册事件监听

若希望简单处理事件,可以在模型的 booted 方法内注册闭包。
若要将处理放入队列异步执行,使用 queueable 辅助函数。

$dispatchesEvents 属性

如果想与 Laravel 的事件系统联动,可以通过 $dispatchesEvents 属性将模型事件映射到自定义事件类。
映射到的事件类会在构造函数中接收模型实例。

创建 Observer 类

若要处理同一模型的多个事件,将闭包排成一列不如整合到 Observer 类中更加清爽。
1

用 Artisan 命令生成类

使用 make:observer 命令生成模板。通过 --model 选项指定模型时,会自动附上相应方法。
将生成 app/Observers/UserObserver.php
2

实现各事件方法

方法名对应事件名。参数中会传入模型实例。
3

将 Observer 注册到 Model

注册方式有 2 种。Laravel 13 推荐使用 #[ObservedBy] 属性。方式 1:#[ObservedBy] 属性(推荐)只需在模型类上添加属性即可完成注册,无需修改 AppServiceProvider
要注册多个 Observer 时,可重复使用属性或以数组形式传入。
方式 2:在 AppServiceProvider 中注册AppServiceProviderboot 方法中调用 observe
#[ObservedBy] 属性位于 Illuminate\Database\Eloquent\Attributes 命名空间。它使用 PHP 8.0 以后的原生语法,在 Laravel 13 中被积极采用。

数据库事务中的 Observer

若模型是在事务内创建或更新,有时你希望 Observer 在事务提交之后执行。实现 ShouldHandleEventsAfterCommit 接口即可获得该行为。
在事务外部执行时,会像往常一样立即执行。

暂时禁用事件

使用 withoutEvents 在特定处理中停止事件

在传给 User::withoutEvents() 的闭包内,任何模型事件都不会触发。

使用 saveQuietly 停止保存事件

想不触发事件地保存模型时使用 saveQuietly
对应的方法在删除、恢复、复制中也提供。

实战用例

自动清理缓存

模型更新或删除时,自动清除相关缓存。

记录审计日志

自动记录模型的变更历史。使用 getDirty() 可以获取变更前后的值。
updating 事件在写入 DB 之前触发,因此 getDirty() 可以取到即将变更的值。如果在 updated 事件之后调用,getDirty() 会为空。

关联模型的自动更新

订单完成时自动更新库存的示例。

下一步

进阶:PHP 属性

一起学习包括 #[ObservedBy] 在内的 Laravel 13 PHP 属性。
最后修改于 2026年7月18日