商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Laravel数据库通知怎么存_Laravel通知记录【详解】

Laravel数据库通知怎么存_Laravel通知记录【详解】

  发布于2026-07-02 阅读(0)

扫一扫,手机访问

先说一个新手最容易踩的坑:数据库通知的表,能不能建对,直接决定了后面的一切能不能跑起来。

很多人一上来就急着执行 php artisan migrate,结果报错 Class 'CreateNotificationsTable' not found——问题出在哪?漏了关键一步:必须先跑 php artisan notifications:table 生成迁移文件,再执行 php artisan migrate。反过来,如果只生成迁移文件却忘了跑 migrate,那表根本不存在,发通知时会直接抛出 SQLSTATE[42S02] 的致命错误,提示你表找不到。

默认的迁移文件只包含基础字段,比如 idtypenotifiable_typenotifiable_iddataread_at 这些。但有个关键细节:默认没有索引。线上环境数据量上来之后,如果查询用户未读通知,就会发现越来越慢。解决办法是在迁移文件里手动加上组合索引:$table->index(['notifiable_type', 'notifiable_id'])。这一步看似小,但对性能的提升非常明显。

Lara vel数据库通知怎么存_Lara vel通知记录【详解】

notifications 表怎么建才不会报错

必须跑 php artisan notifications:table,再执行 php artisan migrate。漏掉前者会导致迁移文件缺失,后者会报 Class 'CreateNotificationsTable' not found;漏掉后者则表根本不存在,发通知时抛出 SQLSTATE[42S02]: Base table or view not found: 1146 Table 'xxx.notifications' doesn't exist

注意:该迁移文件默认只含基础字段(idtypenotifiable_typenotifiable_iddataread_at 等),不带索引。线上环境建议手动在迁移里加组合索引:$table->index(['notifiable_type', 'notifiable_id']),否则查用户未读数会慢。

via() 返回 ['database'] 但没存进去?检查这三点

数据库通知看似简单,但卡住基本都出在这几个地方:

  • 目标模型没 use Notifiable trait —— 比如自定义的 App\Models\Admin 忘了加,notify() 方法根本不存在
  • toDatabase() 方法返回的不是数组,比如误写成 return $this->reply->toArray(); 而没包装成键值对,结果存进 data 字段的是空字符串或 null
  • 通知类构造函数里传入的模型被 eager loading 或 soft delete 影响,导致 $this->reply->user 为 null,toDatabase() 中取 $this->reply->user->nameTrying to get property 'name' of non-object,整个通知静默失败(Lara vel 默认不抛异常)

toDatabase() 返回的数据结构怎么设计才好查好展

data 字段是 JSON,但别把它当黑盒乱塞。前端要渲染「XX 在帖子《YYY》中回复了你」,后端就该明确提供可读字段:

推荐这样返回:

return [    'message' => "在《{$topic->title}》中回复了你",    'link' => $topic->link(['#reply'.$this->reply->id]),    'topic_id' => $topic->id,    'reply_id' => $this->reply->id,    'actor_name' => $this->reply->user->name ?? '已注销用户',];

不推荐这样:

– 只返回原始 $this->reply->toArray(),字段多且嵌套深,前端解析成本高
– 把 HTML 片段拼好塞进去,违反前后端分离原则,也难做国际化
– 缺少 linktopic_id,导致点击通知跳转逻辑得额外查库

unreadNotifications 性能差?别直接遍历

$user->unreadNotifications 是 Eloquent 关系,底层是 where read_at is null 查询。如果用户有几千条未读,这个集合加载太重。

更实用的做法是:

  • 只取最新 20 条:$user->unreadNotifications()->latest()->limit(20)->get()
  • 需要总数时用 count() 而非 load 后 count:$user->unreadNotifications()->count()
  • 标记已读别用循环:$user->unreadNotifications->markAsRead() 是 N+1,改用 $user->unreadNotifications()->update(['read_at' => now()])

真正容易被忽略的是:notification 的 data 字段一旦存了大对象(比如带 a vatar URL 的完整用户数据),单条记录可能超 10KB,批量读时 IO 和内存压力会陡增——宁可前端按需拉取关联数据,也别在 data 里冗余存。

本文转载于:https://www.php.cn/faq/2466787.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注