Laravel 13 通知系统详解 Laravel 的通知系统提供了一种优雅的方式来发送各种类型的通知,支持邮件、短信、数据库、Slack 等多种渠道。
创建通知 生成通知类 1 2 php artisan make:notification OrderShipped php artisan make:notification InvoicePaid --markdown=mail.invoice.paid
通知类结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <?php namespace App \Notifications ;use Illuminate \Bus \Queueable ;use Illuminate \Notifications \Notification ;use Illuminate \Notifications \Messages \MailMessage ;use Illuminate \Notifications \Messages \DatabaseMessage ;use App \Models \Order ;class OrderShipped extends Notification { use Queueable ; public function __construct ( public Order $order ) {} public function via (object $notifiable ): array { return ['mail' , 'database' ]; } public function toMail (object $notifiable ): MailMessage { return (new MailMessage ) ->subject ('Order Shipped' ) ->greeting ('Hello!' ) ->line ('Your order has been shipped.' ) ->action ('Track Order' , route ('orders.track' , $this ->order->id)) ->line ('Thank you for your purchase!' ); } public function toDatabase (object $notifiable ): array { return [ 'order_id' => $this ->order->id, 'message' => 'Your order has been shipped.' , ]; } }
发送通知 使用 Notifiable trait 1 2 3 4 5 6 7 8 use Illuminate \Notifications \Notifiable ;class User extends Model { use Notifiable ; } $user ->notify (new OrderShipped ($order ));
使用 Notification 门面 1 2 3 4 5 use Illuminate \Support \Facades \Notification ;use App \Notifications \OrderShipped ;Notification ::send ($users , new OrderShipped ($order ));Notification ::sendNow ($users , new OrderShipped ($order ));
通知渠道 邮件渠道 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public function toMail (object $notifiable ): MailMessage { return (new MailMessage ) ->subject ('Order Shipped' ) ->from ('orders@example.com' , 'Store' ) ->greeting ('Hello ' . $notifiable ->name . '!' ) ->line ('Your order #' . $this ->order->id . ' has been shipped.' ) ->action ('Track Order' , $this ->order->trackingUrl ()) ->line ('Estimated delivery: ' . $this ->order->estimatedDelivery ()) ->line ('Thank you for shopping with us!' ); } public function toMail (object $notifiable ): MailMessage { return (new MailMessage ) ->markdown ('mail.order.shipped' , [ 'order' => $this ->order, ]); }
数据库渠道 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public function toDatabase (object $notifiable ): array { return [ 'order_id' => $this ->order->id, 'tracking_number' => $this ->order->tracking_number, 'message' => 'Your order has been shipped.' , ]; } public function toDatabase (object $notifiable ): DatabaseMessage { return new DatabaseMessage ([ 'title' => 'Order Shipped' , 'body' => 'Your order has been shipped.' , 'action_url' => route ('orders.track' , $this ->order->id), ]); }
广播渠道 1 2 3 4 5 6 7 8 9 10 11 12 13 14 use Illuminate \Notifications \Messages \BroadcastMessage ;public function toBroadcast (object $notifiable ): BroadcastMessage { return new BroadcastMessage ([ 'order_id' => $this ->order->id, 'message' => 'Your order has been shipped.' , ]); } public function broadcastOn ( ) { return new PrivateChannel ('user.' .$this ->notifiable->id); }
SMS 渠道 1 2 3 4 5 6 7 8 use Illuminate \Notifications \Messages \VonageMessage ;public function toVonage (object $notifiable ): VonageMessage { return (new VonageMessage ) ->content ('Your order has been shipped!' ) ->from ('15554443333' ); }
Slack 渠道 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 use Illuminate \Notifications \Messages \SlackMessage ;public function toSlack (object $notifiable ): SlackMessage { return (new SlackMessage ) ->from ('Order Bot' , ':package:' ) ->to ('#orders' ) ->content ('Order #' . $this ->order->id . ' has been shipped!' ) ->attachment (function ($attachment ) { $attachment ->title ('Order Details' , route ('orders.show' , $this ->order->id)) ->fields ([ 'Customer' => $this ->order->user->name, 'Total' => '$' . number_format ($this ->order->total, 2 ), 'Status' => 'Shipped' , ]); }); }
自定义渠道 创建自定义渠道 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php namespace App \Channels ;use Illuminate \Notifications \Notification ;class SmsChannel { public function send (object $notifiable , Notification $notification ): void { $message = $notification ->toSms ($notifiable ); $phone = $notifiable ->routeNotificationFor ('sms' ); app ('sms' )->send ($phone , $message ); } }
使用自定义渠道 1 2 3 4 5 6 7 8 9 public function via (object $notifiable ): array { return ['mail' , \App\Channels\SmsChannel ::class ]; } public function toSms (object $notifiable ): string { return "Your order #{$this->order->id} has been shipped!" ; }
通知路由 自定义邮件路由 1 2 3 4 5 6 7 class User extends Model { public function routeNotificationForMail ( ): string { return $this ->email; } }
自定义 SMS 路由 1 2 3 4 5 6 7 class User extends Model { public function routeNotificationForVonage ( ): string { return $this ->phone; } }
自定义 Slack 路由 1 2 3 4 5 6 7 class User extends Model { public function routeNotificationForSlack ( ): string { return $this ->slack_webhook_url; } }
队列通知 队列发送 1 2 3 4 5 6 7 8 9 class OrderShipped extends Notification { use Queueable ; public function __construct ( ) { $this ->onQueue ('notifications' ); } }
延迟发送 1 $user ->notify ((new OrderShipped ($order ))->delay (now ()->addMinutes (5 )));
数据库通知 创建通知表 1 2 php artisan notifications:table php artisan migrate
访问通知 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $user = User ::find (1 );foreach ($user ->notifications as $notification ) { echo $notification ->type; echo $notification ->data['message' ]; echo $notification ->created_at; } $unread = $user ->unreadNotifications;$notification ->markAsRead ();$user ->unreadNotifications->markAsRead ();$notification ->delete ();$user ->notifications ()->delete ();
通知事件 监听事件 1 2 3 4 5 6 7 8 9 10 11 12 13 use Illuminate \Support \Facades \Event ;Event ::listen (function (\Illuminate\Notifications\Events\NotificationSent $event ) { $event ->channel; $event ->notifiable; $event ->notification; $event ->response; }); Event ::listen (function (\Illuminate\Notifications\Events\NotificationFailed $event ) { });
测试通知 通知伪造 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 use Illuminate \Support \Facades \Notification ;use App \Notifications \OrderShipped ;public function test_order_shipped_notification ( ): void { Notification ::fake (); $order = Order ::factory ()->create (); $user = User ::factory ()->create (); $user ->notify (new OrderShipped ($order )); Notification ::assertSentTo ($user , OrderShipped ::class ); Notification ::assertSentTo ( $user , OrderShipped ::class , function ($notification ) use ($order ) { return $notification ->order ->id === $order ->id ; } ); Notification ::assertNotSentTo ($user , InvoicePaid ::class ); Notification ::assertNothingSent (); }
最佳实践 1. 使用队列 1 2 3 4 5 6 7 8 class OrderShipped extends Notification { use Queueable ; } $user ->notify (new OrderShipped ($order ));
2. 条件渠道 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public function via (object $notifiable ): array { $channels = ['database' ]; if ($notifiable ->email_notifications) { $channels [] = 'mail' ; } if ($notifiable ->sms_notifications) { $channels [] = 'vonage' ; } return $channels ; }
3. 分离通知逻辑 1 2 3 4 5 6 7 8 9 class OrderShipped extends Notification {}class OrderDelivered extends Notification {}class OrderCancelled extends Notification {}class OrderNotification extends Notification { public function __construct ($type ) {} }
总结 Laravel 13 的通知系统提供了强大而灵活的通知发送能力。通过合理使用多种通知渠道、队列发送和数据库通知,可以构建出完善的通知系统。记住使用队列发送通知以避免阻塞请求、根据用户偏好选择通知渠道、并充分利用通知事件来跟踪通知状态。通知是用户沟通的重要渠道,良好的通知体验可以提升用户满意度。