Eloquent 模型事件和监听的三种方式(大呼牛逼)

未匹配的标注

学习链接

xueyuanjun.com/post/9713

所有支持的模型事件

在 Eloquent 模型类上进行查询、插入、更新、删除操作时,会触发相应的模型事件(关于事件我们后面会单独讲),不管你有没有监听它们。这些事件包括:

retrieved:获取到模型实例后触发
creating:插入到数据库前触发
created:插入到数据库后触发
updating:更新到数据库前触发
updated:更新到数据库后触发
saving:保存到数据库前触发(插入/更新之前,无论插入还是更新都会触发)
saved:保存到数据库后触发(插入/更新之后,无论插入还是更新都会触发)
deleting:从数据库删除记录前触发
deleted:从数据库删除记录后触发
restoring:恢复软删除记录前触发
restored:恢复软删除记录后触发

有什么用?

可以 做记录日志,等操作

如何用?

通过静态方法监听模型事件

编写服务提供者的 boot 方法如下代码:

// app/Providers/EventServiceProvider.php

public function boot()
{
    parent::boot();

    // 监听模型获取事件
    User::retrieved(function ($user) {
        Log::info('从模型中获取用户[' . $user->id . ']:' . $user->name);
    });
}

那么当你调用模型的 获取方法,如 find。
就会触发一个写入日志的操作。

通过订阅者监听模型事件

  1. 创建对应的事件类
    php artisan make:event UserDeleting
    php artisan make:event UserDeleted

在这两个事件类中都添加 $user 属性并在构造函数中传入

  1. 将 Eloquent 支持的模型事件与自定义的事件类建立映射关系

通过 $dispatchesEvents 属性来完成,在 User 模型类中建立模型事件与自定义事件类的映射


protected $dispatchesEvents = [
    'deleting' => UserDeleting::class,
    'deleted' => UserDeleted::class
];

当我们触发 deletingdeleted 事件时,底层会将其转化为触发 UserDeletingUserDeleted 事件

  1. 最后将事件类注册到监听器类中,从而完成模型事件监听闭环。

通过在 EventServiceProviderlisten 属性中为每个事件绑定对应的监听器类

  1. 也可以使用订阅者类 app/Listeners 目录下创建一个 UserEventSubscriber.php 文件作为订阅者类

编写后,在EventServiceProvider 中进行注册即可。

详情请看学习链接。

通过观察者监听模型事件

观察者可以看作是上述订阅者处理模型事件的简化版本,我们不需要自定义事件类,不需要建立映射关系,只需要在观察者类中将需要监听的事件定义为同名方法,并在相应方法中编写业务处理代码即可。当某个模型事件触发时,Eloquent 底层会去该模型上注册的观察者类中通过反射查找是否定义了对应的方法,如果定义了则执行相应的逻辑,否则忽略。

1.初始化观察者

我们通过 Artisan 命令初始化针对 User 模型的观察者:

php artisan make:observer UserObserver --model=User

默认生成的 UserObserver 会为 createdupdateddeletedrestoredforceDeleted(强制删除) 事件定义一个空方法:

这里我们将编写保存模型时涉及的模型事件,包括 savingcreatingupdatingupdatedcreatedsaved

最后代码大致如下:

<?php

namespace App\Observers;

use App\User;
use Illuminate\Support\Facades\Log;

class UserObserver
{
    public function saving(User $user)
    {
        Log::info('即将保存用户到数据库[' . $user->id . ']' . $user->name);
    }

    public function creating(User $user)
    {
        Log::info('即将插入用户到数据库[' . $user->id . ']' . $user->name);
    }

    public function updating(User $user)
    {
        Log::info('即将更新用户到数据库[' . $user->id . ']' . $user->name);
    }

    public function updated(User $user)
    {
        Log::info('已经更新用户到数据库[' . $user->id . ']' . $user->name);
    }

    public function created(User $user)
    {
        Log::info('已经插入用户到数据库[' . $user->id . ']' . $user->name);
    }

    public function saved(User $user)
    {
        Log::info('已经保存用户到数据库[' . $user->id . ']' . $user->name);
    }
}

2. 注册到指定模型

注册到 User 模型上才能生效,我们可以在 EventServiceProviderboot 方法中完成该工作

代码如下:

public function boot()
{
    parent::boot();

    User::observe(UserObserver::class);

    ...
}

结语

至此,我们已经介绍完了三种监听 Eloquent 模型事件的方法和使用方式,如何选择,视情况而定。如果只是监听一两个模型事件,第一种方式比较合适;如果仅仅监听系统支持的模型事件,并且要监听多个模型的多个事件,观察者是最佳选择;如果还要在模型类上监听更多系统模型事件之外的自定义事件,则使用订阅者来监听比较合适。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
wangchunbo
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~