直接用 event() 或 Event::dispatch() 均可触发事件,二者底层相同;90%“不生效”源于注册错误、未运行 event:cache 或事务阻塞。

直接用 event() 或 Event::dispatch() 就能触发,没别的前置动作 —— 但 90% 的“不生效”问题出在注册、缓存或事务陷阱里,不是调用方式错了。
event() 和 Event::dispatch() 到底选哪个?
两者底层完全一样,都走同一个 Dispatcher 实例,没有功能差异。
-
event(new OrderShipped($order))更轻量,适合控制器里一行带过 -
Event::dispatch(new OrderShipped($order))显式调用类名,IDE 补全友好,静态分析更稳 - 都不支持链式写法(比如
->delay(...)),那是队列任务的语法,事件本身不处理延迟 - 返回值恒为
null,别指望靠返回值判断监听器是否执行成功
监听器没反应?先查这三件事
绝大多数“事件没触发”其实是静默失败,根本没走到监听器逻辑里。
-
EventServiceProvider::$listen里事件类路径写错,比如漏了App\Events\前缀,或监听器类名拼错 - 改完
$listen数组后,**生产环境没跑php artisan event:cache** → Laravel 直接跳过加载,不报错也不执行 - 事件在数据库事务里触发,而监听器做了同步耗时操作(如发邮件),又没实现
ShouldQueue→ 请求卡住、超时,你以为“没执行”,其实是阻塞住了
模型事件和自定义事件能混着用吗?顺序怎么控?
不能默认混用顺序。Eloquent 的 created、saved 是模型层自动触发的,event(new ...) 是你手动触发的,它们互不感知。
- 如果你在
Order::created回调里再event(new OrderShipped(...)),那后者一定晚于前者 - 但反过来不行:不要在
OrderShipped监听器里依赖$order->wasRecentlyCreated,因为模型事件早已结束 - 想确保某逻辑在“模型落库 + 所有模型事件完成”之后运行?用
DB::afterCommit(),或者把关键动作放进队列监听器(天然异步,避开事务可见性问题) - 注意:
created这类模型事件在 INSERT 后立刻触发,**哪怕事务最终回滚,监听器也已执行** → 邮件发了但订单没存成,是高频数据不一致源头
监听器抛异常会中断整个请求吗?
默认同步模式下,会。一个监听器 throw new Exception,后续所有监听器跳过,且 event() 调用直接报错,HTTP 响应失败。
- 不想让通知失败拖垮主流程?监听器加
implements ShouldQueue,异常只影响队列任务,不影响接口响应 - 必须同步但又要容错?在
handle()里自己try/catch,记录日志但不throw - 别在监听器里返回值做业务判断 —— Laravel 事件系统根本不收集、不透传任何返回值
最常被忽略的点:事件注册后不跑 event:cache,生产环境就等于没注册;还有事务里同步发邮件这种“看着没问题、上线就炸”的组合,得提前拆到队列里。


















