消息通知
简介
除了支持 发送邮件之外,Laravel 还支持通过多种频道发送通知,包括邮件、短信 (通过 Nexmo),以及 Slack。通知还能存储到数据库以便后续在 Web 页面中显示。
通常,通知都是简短、有信息量的消息,用于通知用户应用中发生了什么。举例来说,如果你是在编写一个在线交易的应用,你应该会通过邮件和短信频道类给用户发送一条 「账单支付」 的通知。
创建通知
Laravel 中一条通知就是一个类 (通常存放在 app/Notifications 文件夹下)。看不到的话不要担心,运行下 make:notification 命令就能创建了:
php artisan make:notification InvoicePaid
这条命令会在 app/Notifications 目录下生成一个新的通知类。这个类包含 via 方法以及一个或多个消息构建的方法 (比如 toMail 或者 toDatabase) ,它们会针对指定的渠道把通知转换为对应的消息。
发送通知
使用 Notifiable Trait
通知可以通过两种方法发送:Notifiable trait 的 notify 方法或 Notification facade。首先让我们来探讨下使用 trait:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable{
use Notifiable;
}
默认的 App\User 模型中使用了这个 trait,它包含着一个可以用来发送通知的方法: notify。 notify 方法需要一个通知实例做参数:
use App\Notifications\InvoicePaid; $user->notify(new InvoicePaid($invoice));
{tip} 记住,你可以在任意模型中使用
Illuminate\Notifications\Notifiabletrait,而不仅仅是在User模型中。
使用 Notification Facade
另外,你可以通过 Notification facade 来发送通知。它主要用在当你给多个可接收通知的实体发送的时候,比如给用户集合发送通知。使用 Facade 发送通知的话,要把可以接收通知和通知的实例传递给 send 方法:
Notification::send($users, new InvoicePaid($invoice));
发送指定频道
每个通知类都会有个 via 方法,它决定了通知会在哪个频道上发送。开箱即用的频道有 mail,database,broadcast,nexmo 和 slack。
{tip} 如果你想使用其他的频道,比如 Telegram 或者 Pusher,你可以去看下社区驱动的 Laravel 通知频道网站。
via 方法接收一个 $notifiable 实例。这个实例将是通知实际发送到的类的实例。你可以用 $notifiable 来决定通知用哪些频道来发送:
/**
* 获取通知发送频道。
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable){
return $notifiable->prefers_sms ? ['nexmo'] : ['mail', 'database'];
}
通知队列
{注:} 使用通知队列前需要配置队列并 开启一个队列任务。
发送通知可能是耗时的,尤其是通道需要调用额外的 API 来传输通知。为了加速应用的响应时间,可以将通知推送到队列中异步发送,而要实现推送通知到队列,可以让对应通知类实现 ShouldQueue 接口并使用 Queueable trait 。 如果通知类是通过 make:notification 命令生成的,那么该接口和 trait 已经默认导入,你可以快速将它们添加到通知类:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
class InvoicePaid extends Notification implements ShouldQueue{
use Queueable;
// ...
}
ShouldQueue 接口被添加到通知类以后,你可以像之前一样正常发送通知,Laravel 会自动检测到 ShouldQueue 接口然后将通知推送到队列:
$user->notify(new InvoicePaid($invoice));
如果你想要延迟通知的发送,可以在通知实例后加上 delay 方法:
$when = now()->addMinutes(10); $user->notify((new InvoicePaid($invoice))->delay($when);
按需通知
有时候你可能需要发送通知给某个用户,但是该用户不存在于应用的用户系统中,要实现这一目的,我们使用 Notification::route 方法在发送通知之前指定特别的通知路由:
Notification::route('mail', 'taylor@example.com')
->route('nexmo', '5555555555')
->notify(new InvoicePaid($invoice));
邮件通知
格式化邮件消息
如果通知支持以邮件方式发送,你需要在通知类上定义一个 toMail 方法。该方法会接收一个 $notifiable 实体并返回 Illuminate\Notifications\Messages\MailMessage 实例。邮件消息可以包含多行文本以及对动作的调用,让我们来看一个 toMail 方法的示例:
/**
* 获取通知对应的邮件。
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable){
$url = url('/invoice/'.$this->invoice->id);
return (new MailMessage)
->greeting('Hello!')
->line('One of your invoices has been paid!')
->action('View Invoice', $url)
->line('Thank you for using our application!');
}
{注:} 注意到我们在
toMail方法中使用了$this->invoice->id,你可以传递任何通知生成消息所需要的数据到通知的构造器。
在这个例子中,我们注册了一条问候、一行文本、对动作的调用以及另一行文本。 MailMessage 对象提供的这些方法让格式化短小的事务邮件变得简单快捷。mail 通道会将消息组件转化为美观的、响应式的、带有纯文本副本的 HTML 邮件模板。下面是一个通过 mail 通道生成的邮件示例:

{注:} 发送邮件通知时,确保在配置文件
config/app.php中设置了name的值,该值将会用在邮件通知消息的头部和尾部。
其他通知格式化选项
除了在通知类中定义多行文本之外,你还可以使用 view 方法来指定一个自定义的、用于渲染通知邮件的模板:
/**
* 获取通知邮件。
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable){
return (new MailMessage)->view(
'emails.name', ['invoice' => $this->invoice]
);
}
此外,你可以从 toMail 方法中返回一个 可邮寄对象 :
use App\Mail\InvoicePaid as Mailable;
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return Mailable
*/
public function toMail($notifiable){
return (new Mailable($this->invoice))->to($this->user->email);
}
错误消息
一些通知会告知用户错误信息,例如失败的订单支付。你可以在构建消息的时候调用 error 方法来指示该邮件消息表示错误信息。在邮件消息中使用 error 方法时,动作按钮将会变成红色:
/** * 获取通知邮件。 * * @param mixed $notifiable *&nb
