Laravel进阶系列笔记--(五)Laravel 四种方法快速使用模型事件

作者: 温新

分类: 【Laravel】

阅读: 2417

时间: 2021-08-13 14:32:07

作者:温新

时间:2021-07-06

hi,我是温新,一名PHPer。

在基础的系列的笔记中提了下模型事件,本篇笔记将对模型事件的使用进行一个快速的记录。

关于模型事件,如用户注册之后给用户发送一封邮件,或者删除一篇文章之后删除对应的图片等等,都可以使用到模型事件。

使用模型事件有一个前提,那就是必须使用模型进行相关的CURD。模型事件有如下事件:

模型事件 含义
retrieved 获取到模型实例后触发
creating 插入到数据库前触发
created 插入到数据库后触发
updating 更新到数据库前触发
updated 更新到数据库后触发
saving 保存到数据库前触发
saved 保存到数据库后触发
deleting 删除数据库记录前触发
deleted 删除数据库记录后触发
restroing 恢复软件删除记录前触发
restored 恢复到软删除记录后触发

方法一:静态方法监听模型事件

快速使用静态方法方式监听模式事件需要在某个服务提供者中的boot方法中完成。如在EventServiceProvider事件服务提供者中进行模型事件监听。

第一步:添加模型事件监听方法

文件:app/Providers/EventServiceProvider.php

public function boot()
{
    // 数据保存到数据库之前调用
    User::saving(function($user) {
        Log::info('这会,我还没有被保存到数据库');
        dd('数据没有入库成功哦,到我这里来了');
    });
}

第二步:创建添加方法

文件了方便起来,我这里直接在路由中进行演示了

// web.php

Route::get('t',function(){
    // 数据插入到数据前会触发saving事件监听
    $user = \App\Models\User::create([
        'name'  =>  'wangwu01',
        'email' =>  'wangwu01@qq.com',
        'password' =>  '123456',
        'lover_id'  =>  0,
    ]);
});

解释一下上述代码。当使用模型添加数据时为它绑定了一个相关的模型事件,这个模型事件saving会在数据被插入到数据之前执行,也就是说,首先会执行User::saveing()模型事件方法,然后才会执行数据入库操作。

模型事件的使用就是这么简单,但是一但当该方法中的模型事件越来越多时,boot方法也就会越来越臃肿,越来越难以维护。因此还可以使用底层

方法二:模型事件监听方式

通过创建事件监听类来监听模型事件需要先创建对应的事件类,然后通过建立映射关系实现。

第一步:创建模型事件监听类

// 监听删除之前的操作
php artisan make:event UserDeleting

第二步:注入$user实例对象

// app/Events/UserDeleting.php
use App\Models\User;
public $user = null;
public function __construct(User $user)
{
    // 删除之前的操作
    dd($user);
    $this->user = $user;
}

第三步:模型类中建立映射关系

// app/Models/User.php
protected $dispatchesEvents = [
    'deleting'  =>  UserDeleting::class,
];

第四步:创建方法

// web.php
Route::get('t',function(){
    $user = \App\Models\User::destroy(129);
});

方法三:使用订阅者监听

第一步:创建模型事件监听类

// 监听删除之前的操作创建创建新的
php artisan make:event UserDeleting

第二步:注入$user实例对象

// app/Events/UserDeleting.php
use App\Models\User;
public $user = null;
public function __construct(User $user)
{
    // 删除之前的操作
    $this->user = $user;
}

第三步:模型类中建立映射关系

// app/Models/User.php
protected $dispatchesEvents = [
    'deleting'  =>  UserDeleting::class,
];

第四步:订阅监听器

手动创建目录及文件

位置:app/Listeners/UserEventSubscriber.php

<?php
namespace App\Listeners;

use App\Events\UserDeleting;
use Illuminate\Support\Facades\Log;

class UserEventSubscriber
{
    // 处理用户删除之前的动作
    public function onUserDeleting($event)
    {
        dd($event);
        Log::info('删除用户之前的动作');
    }
    // 如有添加之前 按照格式添加对应的方法

    // 注册监听器
    public function subscribe($events)
    {
        $events->listen(
            UserDeleting::class,
            UserEventSubscriber::class . '@onUserDeleting'
        );
    }
}

第四步:注册订阅者

// app/Providers/EventServiceProvider.php
use App\Listeners\UserEventSubscriber;
protected $subscribe = [
    UserEventSubscriber::class
];

第五步:测试删除

// web.php
Route::get('t',function(){
    $user = \App\Models\User::destroy(129);
});

方法四:使用观察者监听模型事件

清除前三种定义的方法与文件。

Laravel提供了使用观察者类来处理模型事件的监听。观察者监听不需要建立对应的映射关系,只需在观察者类中定义模型监听事件的同名方法即可。

第一步:创建User模型的观察者监听类

php artisan make:observer UserObserver --model=User

第二步:添加处理删除前的监听方法 文件:app/Observers/UserObserver.php

// 删除之前的操作
public function deleting(User $user)
{
    dd($user);
}

默认是有一些方法的,这里用不上

第三步:EventServiceProvider注册观察者

写好观察者后需要将User模型注册到事件服务提供者。

use App\Models\User;
public function boot()
{
    User::observe(UserObserver::class);
}

第四步:测试

Route::get('t',function(){
    $user = \App\Models\User::destroy(129);
});

我是温新

每天进步一点点,就一点点

请登录后再评论