初识事件监听
前言
在《L02 Laravel 教程 - Web 开发实战进阶 ( Laravel 8.x )》的3.7节——认证后的提示
中就用到了事件监听。
虽然laravel提供了一套成熟的注册登录的功能。在注册时,需要用户邮件认证,但是当用户点击认证邮件中的链接后,就注册成功并跳转到主页。但是问题是没有任何反馈,这样的体验很不好。邮件认证的逻辑在vendor/laravel/ui/auth-backend/VerifiesEmails.php
中,理论上只要修改验证成功后的逻辑就好了,但是课程中提到修改vendor/laravel/ui/auth-backend/VerifiesEmails.php
文件是不可取的。那该怎么办呢?就涉及到今天这篇博客的主题了——事件监听。通过对Verified
事件进行监听,就可以轻松的解决这个问题。
两个例子:
教程中并没有对事件监听进行展开,文档写的也很抽象,还是通过两个例子来认识事件监听吧:
1. 实现文章浏览的计数。
场景:用户浏览文章后,浏览数+1。
具体实现:
1.1 注册事件和监听器
在App\Providers\EventServiceProvider
中注册所有的事件监听者。具体如下:
protected $listen = [
'App\Events\BlogView' => [
'App\Listeners\BlogViewListener',
],
];
// 键为事件,值为监听器。
1.2 生成事件和监听器
在命令行中执行php artisan event:generate
,此命令将生成 EventServiceProvider 中列出的、尚不存在的任何事件或监听器。
1.2.1 自动生成的事件文件app/Events/BlogView.php
如下:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class BlogView
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
1.2.2 自动生成的监听器文件app/Listeners/BlogViewListener.php
如下:
<?php
namespace App\Listeners;
use App\Events\BlogView;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class BlogViewListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param \App\Events\BlogView $event
* @return void
*/
public function handle(BlogView $event)
{
//
}
}
1.3 定义事件:考虑到要处理帖子模型,修改BlogView.php的构造器,在实例化的时候就将post
实例赋值给post
属性。(对事件的处理视具体情况而定)
<?php
namespace App\Events;
use App\Models\Post;
...
class BlogView
{
...
public $post;
public function __construct(Post $post)
{
$this->post = $post;
}
...
}
1.4 定义监听器:事件发生时,浏览数+1。
<?php
namespace App\Listeners;
...
class BlogViewListener
{
...
public function handle(BlogView $event)
{
$post = $event->post;
dd('浏览数+1!');
}
}
1.5 触发事件:当用户查看文章的时候就触发。
<?php
namespace App\Http\Controllers;
use App\Models\Post;
// 注意这里需要引入BlogView类。
use App\Events\BlogView;
...
class PostController extends Controller
{
...
public function show(){
$post = Post::find(1);
// 触发事件
event(new BlogView($post));
return view('post.show');
}
}
1.6 结果:
2. 物流发货后,发短信通知用户。
前辈的这篇博客——记录下学习笔记(Laravel 中的事件监听)写的已经很清楚了,就不再赘言。
什么是事件?
在第一个例子中,事件是查看文章。
在第一个例子中,事件是物流发货。
感觉事件可以是任何动作。
什么是监听器?
不太好下定义,但是可以通过监听器的功能来理解什么是监听器。当监听器用于监听事件,事件一旦触发,就执行相应的逻辑。
具体步骤
1. 注册事件和监听器。
2. 生成事件和监听器。
3. 定义事件和监听器。
4. 触发事件。
注意事项
1. 如果希望再某个类的某个动作中触发事件,需要在该类中引入事件类。例如:在第一个例子中,是在PostController
类的show
动作中触发了事件,所以需要在PostController
类中引入BlogView
事件类:
<?php
// 注意这里需要引入BlogView类。
use App\Events\BlogView;
...
class PostController extends Controller
{
...
}
2. 一个事件可以由多个监听器监听。在第二个例子中,物流发货后,我希望可以同时发送短信和微信通知用户,可以通过定义两个监听器实现:
protected $listen = [
'App\Events\OrderEvent' => [
'App\Listeners\sendModel',
'App\Listeners\sendPhone',
]
];
感谢laravel-china社区
laravel框架很多功能都封装好了,所以在学课程的3.7节时,就感觉事件监听不难。但是我去看文档的时候,又看的迷迷糊糊的。不过幸好有很多前辈在这个社区写过很多优秀的,关于事件监听的博客,所以我很容易就收集到了例子。在这些例子中才对事件监听有一点感觉,才知道该怎么用。
参考:
3. 文档
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: