Laravel 9配置Notification Events后监听器未触发问题
Laravel 9 队列通知事件/监听器不触发排查方案
按以下优先级逐一排查,绝大多数场景都能快速定位问题:
第一步:检查命名空间引入
打开app/Providers/EventServiceProvider.php,确认文件顶部正确引入了所有事件、监听器的完整命名空间,缺项直接补全:use Illuminate\Notifications\Events\NotificationSending; use Illuminate\Notifications\Events\NotificationSent; use App\Listeners\CheckNotificationStatus; use App\Listeners\LogNotification;命名空间缺失是该问题最高发的原因,框架会默认在当前Provider的命名空间下查找事件类,匹配不到正确事件就不会触发任何监听器。
第二步:清理缓存+重启队列进程
队列Worker是常驻内存进程,代码修改后不会自动重载,执行以下命令重置环境:php artisan optimize:clear php artisan queue:restart本地调试阶段不要执行配置缓存、路由缓存类命令,避免新配置不生效。
第三步:排查通知本身的拦截逻辑
打开OrderConfirmationNotification通知类:- 如果类中定义了
shouldSend方法,确认该方法不会返回false,返回false时通知会直接被丢弃,不会触发任何发送相关事件 - 确认
toMail方法逻辑正常,没有抛出异常、没有返回空内容,接收方邮箱格式合法
示例拦截逻辑参考:
// 该方法返回false时通知直接终止,不会进入事件流程 public function shouldSend($notifiable, $channel) { return true; }- 如果类中定义了
第四步:调整测试方式避免误判
队列任务运行在后台CLI进程中,监听器里的dd()输出只会出现在启动队列Worker的命令行窗口,不会显示在浏览器页面,很容易被误判为事件没触发。
测试阶段可以先临时把通知类的ShouldQueue接口移除,改成同步发送模式验证监听逻辑,或者把dd()替换为日志写入,去storage/logs/laravel.log查看输出:public function handle(NotificationSent $event) { logger()->info('通知发送事件触发', ['response' => $event->response]); }第五步:确认事件类路径正确
不要混淆通知事件和原生Mail类的事件,Laravel 9通知体系对应的发送前、发送后事件固定为:- 发送前:
Illuminate\Notifications\Events\NotificationSending - 发送后:
Illuminate\Notifications\Events\NotificationSent
错用Mail组件的MessageSending/MessageSent事件无法监听到通知的发送行为。
- 发送前:
内容的提问来源于stack exchange,提问作者Mohsen
相关产品推荐
相关产品推荐

