Laravel学习记录--Laravel事件系统

Laravel的事件提供了一个简单的观察者实现,能够订阅和监听应用中发生的各种事件,事件类保存在app\Events目录中,这些事件的监听器被保存在app\Listeners当然这些目录只有使用Artisan命令来生成事件和监听器时才会被自动创建。
注册事件和监听器
Larave中的app\Providers\EventServiceProviderlisten数组
键为事件
值为事件对应的监听器
我们可根据需求向里面添加事件
如注册一个删除事件 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,deletedrestored,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到两个模型事件

发布了44 篇原创文章 · 获赞 1 · 访问量 1573

猜你喜欢

转载自blog.csdn.net/weixin_45143481/article/details/104122279