Laravel 的通知系统提供了统一的 API 来发送通知到多种频道,包括邮件、短信(通过 Nexmo 或 Twilio)、Slack、数据库、广播等。你可以轻松地向用户发送重要提醒、订单状态更新、系统警报等。本章将带你全面掌握 Laravel 通知系统的用法。
首先,确保你的 Laravel 版本 ≥ 5.3(通知系统原生支持)。对于数据库通知,你需要创建通知表:
php artisan notifications:table
php artisan migrate
这会在数据库中创建 notifications 表,用于存储通知记录。
使用 Artisan 命令快速创建通知类,例如订单发货通知:
php artisan make:notification OrderShipped
生成的类位于 app/Notifications/OrderShipped.php。它包含两个方法:via() 指定使用的频道,以及 toMail()、toDatabase() 等针对特定频道的输出方法。
有两种方式发送通知:
notify() 方法(模型需使用 Notifiable trait)。Notification Facade 的 send() 方法。
use App\Models\User;
use App\Notifications\OrderShipped;
$user = User::find(1);
$user->notify(new OrderShipped($order));
User 模型默认已引入 Illuminate\Notifications\Notifiable trait。
use Illuminate\Support\Facades\Notification;
use App\Notifications\OrderShipped;
Notification::send($users, new OrderShipped($order));
$users 可以是集合或数组,会批量发送通知。
邮件通知是最常用的频道。在通知类的 toMail() 方法中定义邮件内容。
use Illuminate\Notifications\Messages\MailMessage;
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('你好!')
->line('您的订单已发货。')
->action('查看订单', url('/orders/'.$this->order->id))
->line('谢谢您的支持!');
}
你也可以使用 Markdown 邮件,提供更美观的模板:
return (new MailMessage)
->subject('订单已发货')
->markdown('emails.orders.shipped', ['order' => $this->order]);
Markdown 模板位于 resources/views/emails/orders/shipped.blade.php,可使用 Laravel 预置的邮件组件。
数据库通知将通知存储在 notifications 表中,便于在应用内显示。在 toDatabase() 方法中返回一个数组,该数组会被 JSON 序列化后存入数据库。
public function toDatabase($notifiable)
{
return [
'order_id' => $this->order->id,
'amount' => $this->order->amount,
'message' => '您的订单已发货!',
];
}
读取用户的通知:
$user = User::find(1);
$notifications = $user->notifications; // 所有通知
$unread = $user->unreadNotifications; // 未读通知
标记为已读:
$user->unreadNotifications->markAsRead();
// 或单条
$notification->markAsRead();
广播通知使用 Laravel 的事件广播系统,通过 WebSocket 将通知实时推送到前端。需配置广播驱动(如 Pusher、Redis)。在 toBroadcast() 方法中返回数据。
use Illuminate\Notifications\Messages\BroadcastMessage;
public function toBroadcast($notifiable)
{
return new BroadcastMessage([
'order_id' => $this->order->id,
'message' => '订单已发货',
]);
}
广播通知会自动推送事件到私有频道 private-App.Models.User.{id},前端需订阅该频道并监听 Illuminate\Notifications\Events\BroadcastNotificationCreated 事件。
via() 中返回 ['database', 'broadcast']。
Laravel 支持通过 Vonage(原 Nexmo)或 Twilio 发送短信,以及通过 Slack 发送消息。需要先安装相应驱动。
use Illuminate\Notifications\Messages\VonageMessage;
public function toVonage($notifiable)
{
return (new VonageMessage)
->content('您的订单已发货!');
}
use Illuminate\Notifications\Messages\SlackMessage;
public function toSlack($notifiable)
{
return (new SlackMessage)
->content('新订单已创建!')
->attachment(function ($attachment) {
$attachment->title('订单详情', url('/orders/1'))
->fields([
'订单号' => 'ORD-123',
'金额' => '$99.99',
]);
});
}
如果内置频道不满足需求,你可以创建自定义频道。首先定义一个类,实现 send 方法:
namespace App\Notifications\Channels;
use Illuminate\Notifications\Notification;
class SmsChannel
{
public function send($notifiable, Notification $notification)
{
$message = $notification->toSms($notifiable);
// 发送短信逻辑...
}
}
然后在通知类的 via() 中返回自定义频道的名称:
public function via($notifiable)
{
return [\App\Notifications\Channels\SmsChannel::class];
}
public function toSms($notifiable)
{
return '您的订单已发货!';
}
发送通知(尤其是邮件、短信)可能耗时较长,建议放入队列。只需让通知类实现 ShouldQueue 接口,并添加 Queueable trait:
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class OrderShipped extends Notification implements ShouldQueue
{
use Queueable;
// ...
}
现在所有通过此通知类发送的操作都会自动推送到队列。你也可以在发送时延迟:
$user->notify((new OrderShipped($order))->delay(now()->addMinutes(10)));
config/mail.php 或通知中指定 from 地址。$user->notifications()->paginate(20) 分页。log 频道或 mailtrap 测试邮件通知,避免真实发送。via() 中可以动态决定发送哪些频道,例如根据用户偏好。routeNotificationForMail()、routeNotificationForVonage() 等方法即可。
public function routeNotificationForMail($notification)
{
return $this->email_address;
}
Laravel 的通知系统提供了一个灵活、可扩展的框架,让你可以轻松地将通知发送到多种渠道。通过结合队列、数据库存储和实时广播,你可以构建出专业级的用户通知体验。掌握这些技能后,你可以应对大多数应用中的通知需求。