跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

Laravel观察者Observer_模型事件监听最佳实践【指南】

Observer 必须手动注册且时机正确:在 AppServiceProvider::boot() 中调用 Model::observe(Observer::class),注册需在模型就绪后;Laravel 不自动加载,类名须严格匹配(如 Post 对应 PostObserver);事件监听应放在模型的 booted() 而非 boot() 中;saving 可中断保存并修改数据,saved 在事务提交后执行;批量操作不触发模型事件;软删除触发 deleting/deleted,硬删触发 forceDeleting/forceDeleted。 Observer 类写好了但事件不触发?八成是没注册,或者注册时机错了。Laravel 从不自动加载 Observer,必须手动绑定到模型,且得在模型已就绪之后执行。 Observer 必须手动注册,不能只放文件 生成
UserObserver
后,
app/Observers/UserObserver.php
文件存在 ≠ 它会生效。Laravel 不扫描目录、不自动发现类。 正确做法:在
AppServiceProvider::boot()
中调用
User::observe(UserObserver::class)
错误做法:只放文件、不注册;或在
EventServiceProvider
的
$listen
里配(那是给事件系统用的,不是 Observer) 如果模型类名是
Post
,Observer 类名必须是
PostObserver
,否则反射失败,IDE 也可能报错 注册时机必须用 booted(),不是 boot() Laravel 10+(及新版 9.x)中,模型事件监听逻辑已移到实例化后的
booted()
钩子,
boot()
仅用于静态初始化,放事件监听器不会触发。
booted()
是
protected static function
,必须定义在模型类内部,例如:
static::created(fn ($user) => Log::debug('User created: '.$user->id))
不要在
boot()
里写
static::created()
,它不会执行 若用 trait 复用逻辑,确保
booted()
没被覆盖,必要时加
parent::booted()
saving 和 saved 的事务行为完全不同 这两个钩子看似只差一个字母,但执行上下文和可靠性差异极大: Laravel 13.2.0 PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。 下载
saving
在事务内、INSERT/UPDATE 前触发,可修改字段值或返回
false
中断保存(比如校验必填字段)
saved
在事务提交后触发,数据已落库,适合发通知、写日志、触发队列任务 在
saving
里调
$model->save()
会递归触发,导致爆栈;在
saved
里改属性再
save()
也无效(已入库) 批量更新不触发任何模型事件
User::where()->update()
、
DB::table()
、
upsert()
这些操作完全绕过 Eloquent 生命周期,Observer 对它无感。 想监听批量变更?要么改用模型循环 +
save()
(注意 N+1),要么在业务层显式调用自定义方法
updated()
只在真实字段变更时触发(依赖
$model->isDirty()
),而
saved()
插入和更新都触发 软删除走
deleting
→
deleted
;硬删才走
forceDeleting
→
forceDeleted
,方法名一个字母都不能错 最容易被忽略的是:Observer 方法里访问
$model->getOriginal('email')
时,
created
事件中它和当前值一样——只有
updated
或
deleted
才真正反映变更前状态。

相关文章