多数情况下,当某个特定事件发生时我们会给用户发生通知,例如当有购买行为时我们会发送发票,或者当用户注册时发送一个欢迎邮件,为了实现这个功能,我们需要这样监听事件:
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
NewPurchase::class => [
SendInvoice::class,
]
];
}
而在事件监听者 SendInvoice 中我们会做一些这样的操作:
class SendInvoice implements ShouldQueue
{
public function handle(NewPurchase $event)
{
$event->order->customer->notify(new SendInvoiceNotification($event->order));
}
}
想法
除了创建一个事件监听者类和一个通知/邮件类外,我们直接把通知/邮件类作为事件监听者岂不是也很酷?比如这样:
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
NewPurchase::class => [
SendInvoiceNotification::class,
]
];
}
这样做之后,事件分发器或创建一个 SendInvoiceNotification 类的实例,并调用 handle() 方法。这样做之后我们就可以直接在通知类的 handle() 方法中发送通知了:
class SendInvoiceNotification extends Notification implements ShouldQueue
{
public $order;
/**
* Handle the event here
*/
public function handle(NewPurchase $event)
{
$this->order = $event->order;
app(\Illuminate\Contracts\Notifications\Dispatcher::class)
->sendNow($event->order->customer, $this);
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)
->line('Your order reference is #'.$this->order->reference);
}
}这里需要注意,我们使用 sendNow() 来阻止通知使用队列功能,因为监听者本身就已经是队列化的了,因为它实现了 ShouldQueue 接口。
邮件功能(Mailables)呢 ?
这里我们可以通过 mailable 来实现相同功能:
class SendInvoiceNotification extends Mailable implements ShouldQueue
{
public $order;
/**
* Handle the event here
*/
public function handle(NewPurchase $event)
{
$this->order = $event->order;
$this->to($event->order->customer)
->send(app(\Illuminate\Contracts\Mail\Mailer::class));
}
public function build()
{
return $this->subject('Order #'.$this->order->reference)->view('invoice');
}
}
总结
我认为这是一种你可以在应用中直接使用的非常简洁的实现方式,它避免了创建一个额外的事件监听者类。你认为呢?