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

作者: 温新

分类: 【Laravel】

阅读: 2135

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

作者:温新

时间:2021-07-06

hi,我是温新,一名PHPer。

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

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

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

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

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

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

文件:app/Providers/EventServiceProvider.php

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">boot</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 数据保存到数据库之前调用</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 0, 0)">User</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">saving</span>(<span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>) {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Log</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">info</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'这会,我还没有被保存到数据库'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(0, 0, 0)">dd</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'数据没有入库成功哦,到我这里来了'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    });</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

第二步:创建添加方法

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

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// web.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Route</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'t'</span>,<span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span>(){</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 数据插入到数据前会触发saving事件监听</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">\App\Models\User</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">create</span>([</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'name'</span>  <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span>  <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'wangwu01'</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'email'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span>  <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'wangwu01@qq.com'</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'password'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span>  <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'123456'</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'lover_id'</span>  <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span>  <span style="box-sizing: border-box;color: rgb(17, 102, 68)">0</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    ]);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">});</span>

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

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

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

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

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

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 监听删除之前的操作</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">artisan</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">make</span>:<span style="box-sizing: border-box;color: rgb(0, 0, 0)">event</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">UserDeleting</span></span>

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

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// app/Events/UserDeleting.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Models\User</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(34, 17, 153)">null</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">__construct</span>(<span style="box-sizing: border-box;color: rgb(0, 0, 0)">User</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 删除之前的操作</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 0, 0)">dd</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">user</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

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

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// app/Models/User.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">protected</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$dispatchesEvents</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> [</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'deleting'</span>  <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span>  <span style="box-sizing: border-box;color: rgb(0, 0, 0)">UserDeleting</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">];</span>

第四步:创建方法

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// web.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Route</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'t'</span>,<span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span>(){</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">\App\Models\User</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">destroy</span>(<span style="box-sizing: border-box;color: rgb(17, 102, 68)">129</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">});</span>

方法三:使用订阅者监听

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

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 监听删除之前的操作创建创建新的</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">artisan</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">make</span>:<span style="box-sizing: border-box;color: rgb(0, 0, 0)">event</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">UserDeleting</span></span>

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

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// app/Events/UserDeleting.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Models\User</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(34, 17, 153)">null</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">__construct</span>(<span style="box-sizing: border-box;color: rgb(0, 0, 0)">User</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 删除之前的操作</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">user</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$user</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

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

// 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);
});

我是温新

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

请登录后再评论