Laravel保存模型时默认触发saving→creating→created→saved(新增)或saving→updating→updated→saved(更新)事件链;saving/saved为通用事件,creating/created和updating/updated分别专用于插入与更新场景。

保存模型时,Laravel 会按固定顺序触发多个事件,关键在于区分“前/后”和“创建/更新”两类场景。只要理解触发时机与返回值影响,就能精准控制逻辑执行位置。
保存时默认触发哪些事件?
无论调用 save()、create() 还是 update(),只要最终走 Eloquent 的持久化流程,都会触发对应事件链:
-
新记录保存(首次插入):依次触发
saving→creating→created→saved -
已有记录更新:依次触发
saving→updating→updated→saved -
saving和saved是通用事件,覆盖新增与更新;creating/created和updating/updated则分别专用于插入或更新场景
如何注册事件监听?两种主流方式
推荐使用观察者(Observer),结构清晰、易维护;事件类方式适合需解耦到队列或跨模块的复杂场景。
-
用观察者监听:运行
php artisan make:observer UserObserver --model=User,在生成的UserObserver类中定义方法,如updating(User $user),然后在User模型的boot()中注册:static::observe(UserObserver::class) -
用 $dispatchesEvents 属性:在模型中声明
protected $dispatchesEvents = ['saving' => UserSaving::class];,再配合php artisan make:event UserSaving创建事件类,构造函数接收模型实例
前事件 vs 后事件:什么时候能改数据?什么时候能阻断?
以 saving 和 saved 为例,它们能力完全不同:
-
saving、creating、updating、deleting等“前事件”中,可修改模型属性(如自动填充字段)、做校验,且返回false可中止后续操作(如阻止保存) -
saved、created、updated、deleted等“后事件”中,数据库已写入完成,适合发通知、清缓存、记录日志;返回值无效,不能阻止操作 - 注意:
updating只在模型确实有字段变更($model->isDirty()为 true)时才触发,避免无意义执行
实战建议:避免踩坑的关键细节
很多问题源于对生命周期和状态判断不准确:
- 想判断「某个字段是否被修改」,别只看当前值,要用
$user->isDirty('email')或对比$user->getOriginal('email')与$user->email - 在
saving中修改时间戳等字段是安全的;但不要在saved中再调用save(),可能引发无限循环 - 涉及事务的逻辑(如需部分回滚),优先在
saving或updating中介入,配合DB::transaction()和保存点控制粒度 - 软删除恢复(
restore())会触发restoring和restored,不是saving/saved


















