最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Laravel5.5实现站内消息通知功能的方法
时间:2026-07-02 10:48:46 编辑:袖梨 来源:一聚教程网
站内信发不出去主因是notifications表未建、Notifiable trait未绑定或队列未运行;DatabaseChannel仅支持基础类型数组序列化;未读统计需避免N+1并注意read_at字段精度;扩展应通过通知类而非修改核心逻辑。
通知发不出去?先确认队列和 DatabaseChannel 是否就位
站内信发不出去,90% 是因为 notifications 表没建、Notifiable trait 没绑定,或队列没跑起来。Laravel 的 Notification::send() 默认走队列,但开发环境常漏配——页面不报错,数据库里 notifications 表空空如也,用户收不到任何提示。
- 运行
php artisan notifications:table生成迁移,再php artisan migrate - 确保用户模型(如
User)声明了use Notifiable;,且类定义里写了use Notifiable; - 开发时临时启用同步模式:在
.env中设QUEUE_CONNECTION=sync - 生产环境必须用
redis或database驱动,并常驻运行php artisan queue:work - 别在通知类里加
implements ShouldQueue,除非你明确要强制进队列——它会绕过QUEUE_CONNECTION=sync
toDatabase() 返回空数组或对象?这是最常踩的序列化坑
DatabaseChannel 只接受纯数组,且只序列化基础类型(string/int/bool/array)。返回对象、Eloquent 模型或未重写 toArray() 的封装类,会导致 data 字段存成空或 JSON 错误。
- 正确写法:
return ['title' => '新回复', 'body' => $this->reply->content, 'link' => '/topics/123']; - 避免:
return new NotificationData(...)或return $this->reply->toArray();(除非你确认该模型toArray()只返回基础类型) -
data字段是 JSON 类型,MySQL 5.7+ 没问题;低版本建议把字段类型设为longtext,防截断 - 自定义字段(如
from_user_id)必须手动塞进返回数组,DatabaseChannel不自动提取模型关系
读未读数慢、markAsRead 失效?N+1 和时间精度是隐形杀手
直接调 $user->unreadNotifications->count() 看似简单,但在列表页循环多个用户时,就是 N+1 查询。更隐蔽的是 markAsRead() 依赖 read_at 字段,而 MySQL 旧版本对 datetime(6) 微秒精度支持不稳定,导致已读状态不生效。
- 查未读数推荐原生查询:
DB::table('notifications')->where('notifiable_id', auth()->id())->whereNull('read_at')->count() - 标记已读优先用
$notification->markAsRead(),而非手动更新read_at;若批量操作,用Notification::markAsRead($notifications) -
read_at字段默认允许 NULL,判断未读必须用whereNull('read_at'),不是where('read_at', null) - 如果需要实时未读总数,考虑缓存
notification_count字段并配合观察者更新,别每次都 COUNT
想扩展功能?别硬改核心逻辑,从 Notification 类入手
站内信不只是“一条记录”,比如要区分消息类型(评论、关注、系统公告)、支持多接收者、带附件或跳转参数。这些都不该动 notifications 表结构或重写 DatabaseChannel,而是靠通知类本身控制。
- 在
via()中动态决定渠道:return $notifiable->prefers_sms ? ['nexmo'] : ['database']; - 不同场景复用同一通知类:传入
$type参数,在toDatabase()中分支返回不同字段 - 需要关联发送者?在构造函数里注入
$sender,然后存进data数组,前端按需展示 - 不想每条都进数据库?
via()返回空数组即可跳过该渠道,不用删类或注释方法
真正难的不是写几行 notify(),而是让 data 字段可维护、查询不拖垮 DB、读写状态不丢帧——这些细节不盯住,上线后才最费时间。
相关文章
- 宝可梦Pokopia流程视频是什么样子的 07-06
- 王者万象棋残局怎样运营-王者万象棋残局运营方式 07-06
- 女神异闻录3Reload史低价格 女神异闻录3Reload最低折扣与购买时机分析 07-06
- 男爵史低价格总览男爵最新优惠折扣消息分享 07-06
- 杀戮尖塔2机器人角色特点有哪些 07-06
- 龙珠超宇宙2史低价格:龙珠超宇宙2历史最低折扣及购买时机分析 07-06