laravel通知系统核心依赖via()返回已注册渠道名的字符串数组,否则静默失败;数据库通知需建表加联合索引,邮件通知须配mail_mailer及正确路由逻辑。

Laravel 9 和 11 的通知系统在核心机制上高度一致,数据库通知与邮件通知的配置逻辑基本相同,差异主要体现在默认依赖版本、队列驱动兼容性及部分配置项命名微调(如 MAIL_MAILER 在 9 中已启用,11 中为强制标准)。真正影响发送效果的不是 Laravel 版本号,而是渠道是否正确注册、驱动是否就位、以及调用方式是否匹配预期。
数据库通知:存数据不外发,需手动建表+读取逻辑
数据库通知本质是把通知内容序列化后写入 notifications 表,供前端拉取或后台展示,它本身不会触发任何外部提醒。
- 先执行迁移命令:
php artisan notifications:table,再运行php artisan migrate创建表 - 通知类中
via()必须返回['database'],且模型必须使用Notifiabletrait -
toDatabase()方法返回纯数组,字段名可自定义,例如:['order_id' => $this->order->id, 'status' => 'shipped'] - 读取未读通知用
$user->unreadNotifications,标为已读调用$notification->markAsRead() - 注意加联合索引:
notifiable_id + notifiable_type,否则大量通知时查询变慢
邮件通知:不配驱动=不发信,关键在 MAIL_MAILER 和路由方法
邮件通知不会自动发出,Laravel 只负责组装和派发;能否真正送达,取决于你是否配好邮件驱动及收件人地址获取逻辑。
-
.env中至少设置:MAIL_MAILER=smtp,并补全MAIL_HOST、MAIL_PORT、MAIL_USERNAME、MAIL_PASSWORD - 在通知类的
toMail()方法里,收件地址必须通过$notifiable->routeNotificationFor('mail')获取,而不是直接写$notifiable->email - 若用户模型邮箱字段不是
email(比如叫contact_email),需在模型中重写routeNotificationForMail()方法 - 模板中避免 N+1:不要在 Blade 模板里层层访问关联模型,应在通知构造函数中预加载或传入必要数据
- 开发阶段可用
log驱动测试:MAIL_MAILER=log,日志里能看到渲染后的邮件内容
渠道组合与静默失败排查:via() 写错=通知消失
很多“通知没发出去”的问题,其实根本没走到邮件或数据库写入环节,而是卡在了渠道判定这一步。
-
via()必须返回字符串数组,如['mail', 'database'];返回空数组、拼写错误(如'maill')、或写了未安装渠道(如'vonage'但没装包),都会导致完全跳过发送 - 确保该渠道已被 Laravel 注册:邮件需
MAIL_MAILER配置有效;数据库无需额外扩展;广播需BROADCAST_DRIVER正确;短信/微信需自行实现渠道类并注册到config/services.php - 修改配置后务必清缓存:
php artisan config:clear,否则旧配置可能被缓存拦截 - 用
Notification::send($users, new XxxNotification)测试时,确认$users是集合或数组,不能传 null 或空值
队列启用:异步发送不是加接口就完事
加了 ShouldQueue 接口只是告诉 Laravel “这个通知要进队列”,但真正执行还得靠队列服务跑起来。
-
.env中设QUEUE_CONNECTION=database或redis,不能留默认的sync - 数据库队列需先运行
php artisan queue:table并迁移;Redis 需服务正常运行 - 启动监听器:
php artisan queue:work,终端保持运行;生产环境建议用 Supervisor 管理进程 - 检查
failed_jobs表,若存在失败记录,说明任务抛异常了,需看日志定位具体错误(如 SMTP 认证失败、视图缺失)











