Observer 类不触发是因为未手动注册或注册时机错误;必须在AppServiceProvider::boot()中用User::observe(UserObserver::class)显式绑定,且模型类需已加载。

Observer 类不触发?大概率是没注册,或者注册时机错了。
Observer 必须手动注册,Laravel 不会自动发现
生成的 UserObserver 放在 app/Observers/ 下,命名再规范也没用——Laravel 5.5 完全不会自动扫描或加载它。不显式绑定,事件永远不进回调。
- 注册位置必须在模型类已加载之后,推荐统一放在
AppServiceProvider::boot()里 - 写法必须是
User::observe(UserObserver::class),不是observe(new UserObserver),也不是数组传多个 - 如果模型用了别名或延迟加载(比如通过字符串引用),确保
User类能被正确解析,否则会报Class 'User' not found - 检查
config/app.php是否误删了Illuminate\Database\DatabaseServiceProvider,它负责启用模型事件调度器
created 和 updated 的触发条件差异极大
created 只在 INSERT 成功后触发;updated 要同时满足:已有主键 + 数据实际变更($model->isDirty() 返回 true)。很多人用 updated 处理“新建后初始化”,结果新建时完全不走。
-
saving和updating在写入前触发,可返回false中断保存;saved和updated已落库,改字段无效 -
saved在 insert 和 update 后都触发;updated仅对 UPDATE SQL 生效,firstOrCreate、updateOrCreate的 insert 分支不触发它 - 批量更新如
User::where(...)->update([...])不触发任何模型事件,包括updated - 想确认字段是否真变了?必须手动加
if ($model->isDirty('email')) { ... },Eloquent 默认不做 dirty check
Observer 方法里不能 throw Exception 来控制流程
在 saving 或 updating 里抛异常,事务不会自动回滚;Laravel 只认 false 返回值作为中断信号。
- 正确拦截方式:
return false;—— Eloquent 会停止后续 persist 操作,且不抛异常 - 在
saved或updated里 throw Exception 已无意义,数据早已写入数据库 - 若需强一致性(比如主表+日志表必须同时成功),应把逻辑移到事件监听器(如
ModelCreated)并包裹在 DB transaction 中,别依赖 Observer 单点控制 - 软删除触发的是
deleting/deleted,不是forceDeleting;恢复软删用restoring/restored
最易被忽略的点:Laravel 5.5 的模型事件默认启用,但如果你项目中调过 Model::unguard() 或修改过事件调度器配置,得回头检查 DatabaseServiceProvider 是否完整加载——否则所有 observer 都静默失效。


















