Observer方法名须严格匹配事件名(如created)、参数唯一且类型正确;注册必须在模型加载后,推荐EventServiceProvider集中配置;saving可修改数据并中断保存,created在提交后触发适合发邮件等操作。

模型观察者不会自动生效,必须显式注册且方法名严格匹配事件名;写错方法名、漏注册、在错误时机调用 User::observe() 是最常见失效原因。
Observer 类怎么写:方法名大小写和参数不能错
Observer 类里每个方法都靠名字被 Laravel 自动调用,不靠继承或注解。比如监听创建后逻辑,必须叫 created(全小写),不是 Created、onCreated 或 handleCreated。
-
created(User $user)接收一个模型实例,不能再加第二个参数(如$event),否则调用失败静默跳过 - 软删除模型想拦截强制删除,得写
forceDeleting,不是deleting—— 后者只对硬删有效 -
retrieved会在每次get()、first()、paginate()的每条记录上执行,滥用会导致 N+1 性能问题 - 想在保存前修改字段并可能中止操作,用
saving;想发邮件或写日志等依赖已落库数据的操作,用created或updated
注册 Observer 必须在模型类加载之后
把 User::observe(UserObserver::class) 写在 AppServiceProvider::boot() 开头,很容易失效——因为此时 User 类可能还没被自动加载,PHP 找不到类,Laravel 不报错也不提示。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- ✅ 正确做法:在
boot()末尾显式use App\Models\User和use App\Observers\UserObserver,再调用User::observe() - ✅ Laravel 9+ 更推荐用
EventServiceProvider的$observe属性集中注册:protected $observe = [ User::class => [UserObserver::class], ];框架会在 boot 阶段自动处理,避开加载顺序问题 - ❌ 别在模型自己的
boot()方法里调static::observe(),容易引发循环依赖 - ❌ 不要放在
AppServiceProvider::register()里,模型类此时肯定没加载
saving vs created:什么时候该用哪个
这两个钩子触发时机和事务边界完全不同,选错会直接导致数据不一致或通知发空。
-
saving在事务内、写入 DB 前执行,可修改属性(如自动生成slug),也可throw new Exception()中断保存 -
created在事务提交后触发,此时$user->id已确定,关联数据可安全查询,适合发邮件、推消息、写审计日志 - 如果在
created里做耗时操作(如调第三方 API),应交由队列:dispatch(new SendWelcomeEmail($user));
否则主请求会卡住,还可能因超时导致事务回滚 -
updating和updated只在字段实际变更时触发(基于isDirty()),而touch()、increment()这类原生 SQL 操作完全绕过它们
关联模型变更不会触发其 Observer
这是最容易被误判的点:Post 观察者里的 deleted 方法,不会因为你调了 $post->comments()->delete() 就自动触发 Comment 的 deleted。
-
$post->comments是 Eloquent 集合,遍历调$comment->delete()才会逐个走 Comment 的观察者 -
Comment::where('post_id', $post->id)->delete()是原生 SQL 删除,彻底跳过模型生命周期,Observer 完全不触发 - 需要联动清理时,要么在 Post 的
deleted里手动查出并逐个delete(),要么用事件系统:event(new PostDeleted($post));
然后另写监听器处理评论 - Observer 方法里访问
$user->posts默认是 null,因为关联关系没预加载,要用$user->load('posts')显式加载

















