Laravel的事件提供了一个简单的观察者实现,能够订阅和监听应用中发生的各种事件,事件类保存在app\Events
目录中,这些事件的监听器被保存在app\Listeners
当然这些目录只有使用Artisan命令来生成事件和监听器时才会被自动创建。
注册事件和监听器
Larave中的app\Providers\EventServiceProvider
的listen
数组
键为事件
值为事件对应的监听器
我们可根据需求向里面添加事件
如注册一个删除事件 UserDeleting
在listen
数组中
protected $listen = [
//键为事件
//值为数组(监听器)
'App\Events\UserDeleting'=>[
'App\Listeners\PrictDelete',
]
];
生成事件&监听器
为每一个事件和监听器手动创建文件是件很麻烦的事情,在这里我们只需将事件和监听器添加到EventServiceProvider
中,在使用php artisan event:generate
命令
该命令会自动生成事件类与监听器类,已经存在的事件与监听器保持不变
手动注册事件
事件通常是在EventServiceProvider
类的$listen
数组注册,但你也可以在EventServiceProvider
类的boot方法中注册基于事件的闭包
public function boot()
{
parent::boot();
Event::listen('event.name', function ($foo, $bar) {
//
});
}
通配符事件监听器
在注册监听器时使用*
通配符参数,这样可以在一个监听器上捕获多个事件
Event::listen('event.*', function ($eventName, array $data) {
//
});
定义事件
在事件的构造函数中,传入参数Model,并设置Model属性 如
public function __construct(Muser $muser)
{
$this->user = $muser;
}
定义监听器
事件监听器的handle
方法传入事件实例。如果你使用了 命令 php artisan event:generate
该命令会自动填充事件类到handle
方法,在handle
方法中你可以键入对应该事件的逻辑
public function handle(UserDeleting $event)
{
dump($event);
}
停止事件传播
你可以通过在监听器的handle
方法中返回false来阻止事件被其他监听器获取
分发事件
分发事件,使用event
函数,这个函数接受一个参数(事件实例),该函数会把事件分发到已经注册的监听器上。由于该函数是全局访问的,你可以在任意地方调用它
public function show(){
$user = Muser::find(1);
event(new UserDeleting($user));//分发事件到监听器
}
监听器打印事件实例
public function handle(UserDeleting $event)
{ //这里键入事件逻辑
dump($event);
}
除自定义事件外Laravel还预定义了一些事件,这些事件会在模型类上进行查询,插入,更新,删除操作时,触发相应事件,即使你没有使用监听器
一起来看一下这些事件
retrieved
:获取模型实例后触发creating
:插入到数据库前触发created
:插入到数据库后触发updating
:更新数据库之前触发updated
:更新数据库之后触发saving
:保存到数据库前触发(插入/更新之前)saved
:保存到数据库后触发(插入/更新之前)deleting
:从数据库删除记录前触发deleted
:从数据库删除记录后触发restoring
:恢复软删除记录前触发restored
:恢复软删除记录后触发
需要注意的是,当我们进行批量操作时,不会触发相应的事件,因为批量操作是走的查询构造器,而不是模型方法。
同样,在这里我们也可以监听这些事件,甚至我们还能将这些事件和我们自定义的事件建立映射关系,使其触发了对应事件,而走我们自定义的事件
在app\Providers\EventServiceProvider
的boot方法中
public function boot()
{
parent::boot();
// 监听模型获取事件
User::retrieved(function ($user) {
dump('模型被获取');
});
}
使系统预定义事件与自定义事件建立映射关系
1.在 app\Providers\EventServiceProvider
的$listen
数组中添加事件
还是以删除模型为例
添加两个事件,分别为UserDeleting(删除前)
和UserDeleted(删除后)
protected $listen = [
'App\Events\UserDeleting'=>[
'App\Listeners\DeleteFirset',
],
'App\Events\UserDeleted'=>[
'App\Listeners\DeleteAter'
]
];
使用命令 php artisan event:generate
创建事件和监听器
在两个事件类中向其构造函数传入参数,Model并设置Model属性
public function __construct(Muser $muser)
{
$this->user = $muser;
}
在Model中建立模型事件与自定义事件的映射,通过$dispatchesEvents属性,该属性是一个数组,键为模型事件,值为自定义事件类
protected $dispatchesEvents = [
'deleting'=>UserDeleting::class,
'deleted'=>UserDeleted::class
]
添加完成后当触发了deleting
时会走我们自定义的UserDeleting
事件
最后我们要监听我们自定义的事件
在监听器的handle方法中传入事件实例,并编写事件逻辑
public function handle(UserDeleted $event)
{
dump('删除后触发这个事件');
}
编写代码触发模型事件
public function show(){
$user = Muser::find(3);
$user->delete();
}
事件监听器队列
如果你的监听器中要执行如发送邮件,或进行HTTP请求等比较满的任务,你可以选择将其丢给队列处理。在开始使用监听器队列之前,请确保你的服务器或本地开发环境中能够配置并启动队列监听器
。。。。这里又是一大堆内容,以后在来补充算了 【队列】
事件订阅者
事件订阅者是一个可以在自身内部订阅多个事件的类,即能够在单个类中定义多个事件处理器。订阅者应该定义subscribe
方法,这个方法接受一个事件分发器的实例,你可以调用给定的事件分发器上的listen
方法来注册事件监听器
编写一个订阅者
listen(event,method)
event
:事件类
method
:当前事件对应的监听器 格式 订阅者类@监听方法
由于使用的是事件订阅者,我们需要使用命令创建事件类
php artisan make:event EventName;//创建一个事件
php artisan make:listener ListenName://创建一个监听器
<?php
namespace App\Listeners;
class UserDel{
//用户删除前的事件
public function onUserDelAgo($event){
dump('删除前');
}
//用户删除后的事件
public function onUserDelAfter($event){
dump('删除后');
}
//为订阅者注册监听事件
public function subscribe($events){
$events->listen(
'App\Events\UserDeleting',
'App\Listeners\UserDel@onUserDelAgo'
);
$events->listen(
'App\Events\UserDeleted',
'App\Listeners\UserDel@onUserDelAfter'
);
}
}
注册事件订阅者
创建号事件订阅者后,我们需将其注册到事件分发器中,你可以在EventServiceProvider
类的$subscribe
属性中注册订阅者
//注册订阅者
protected $subscribe = [
'\App\Listeners\UserDel'
];
测试删除操作
public function show(){
$user = Muser::find(5);
$user->delete();
}
事件观察者
观察者可以看作是订阅者处理模型事件的简化版本,我们不需要自定义事件类,也不需要建立映射关系,只需要在观察者类中将需要监听的事件定义为同名方法,在相应的方法编写事件逻辑即可
要使用观察者,你的Laravel版本必须>=5.7
注册观察者,使用命令 php artisan make:observer ObserverName --model = Muser
生成的观察者会为created
,updated
,deleted
,restored
,forceDeleted
事件定义一个空方法
为了测试删除操作我们需定义 deleting(删除前),这个模型事件方法
<?php
namespace App\Observers;
use App\User;
class UserDel
{
/**
* Handle the user "created" event.
*
* @param \App\User $user
* @return void
*/
public function created(User $user)
{
//
}
/**
* Handle the user "updated" event.
*
* @param \App\User $user
* @return void
*/
public function updated(User $user)
{
//
}
public function deleting(User $user){
dump('删除前');
}
/**
* Handle the user "deleted" event.
*
* @param \App\User $user
* @return void
*/
public function deleted(User $user)
{
dump('删除后')
}
/**
* Handle the user "restored" event.
*
* @param \App\User $user
* @return void
*/
public function restored(User $user)
{
//
}
/**
* Handle the user "force deleted" event.
*
* @param \App\User $user
* @return void
*/
public function forceDeleted(User $user)
{
//
}
public function deleting(User $user){
dump('删除前');
}
定义好观察者后,需将其注册到对应的模型,我们可以在app\Providers\EventServiceProvider
类的 boot
方法中实现
public function boot()
{
parent::boot();
Muser::observe(UserDel::class);
}
编写测试代码
public function show(){
$user = Muser::find(5);
$user->delete();
}
打印结果
静态方法监听模型事件
除了使用 订阅者,观察者监听模型事件外,还可使用静态方法监听模型事件
在app\Providers\EventServiceProvider
类的 boot
方法中实现
public function boot()
{
parent::boot();
//监听模型删除前事件
Muser::deleting(function(Muser $muser){
//键入事件逻辑
dump('删除前');
});
Muser::deleted(function(Muser $muser){
//键入事件逻辑
dump('删除后')
})
}
上述代码表示在Muser模型上监听deleting和deleted事件,不过这种静态监听只适用于监听1到两个模型事件