网络编程
位置:首页>> 网络编程>> php编程>> 详解Laravel模型事件和模型事件在Trait中的使用

详解Laravel模型事件和模型事件在Trait中的使用

作者:多厘  发布时间:2023-06-17 17:19:28 

标签:Laravel,模型事件,Trait

模型事件

Laravel 模型事件允许你监听模型生命周期内的事件, 并且通过这个事件去做一些模型通用性的东西, 例如检查用户修改了那个字段, 将字段的什么值修改成另外的什么值, 等等.

事件类型

# 当现有模型被数据库检索时
retrieved
# 当一个新的模型被第一次保存时
creating
created
# 对一个已经存在于数据库的模型调用 save 方法
updating
updated
# 当模型数据被删除时
deleting
deleted
# 当创建和更新执行时都会调用
saving
saved
# 当启用软删除的数据被恢复时
restoring
restored
# 当启用软删除的数据被强制删除时
forceDeleted
# 复制
replicating
# 指定模型的指定事件被触发时(注意 $name 前有个空格)
# event 对应以上的事件类型
# name 对应的是模型的类名称
eloquent.{$event}: {$name}

以上事件类型的注册可以通过 boot 方法注册

boot 方法和事件注册

模型在执行时候仅仅执行一次的 boot 方法, 可以理解为模型启动时候的注册钩子方法我们看下示例

<?php
Class PamAccount extend Model
{
   public static function boot()
   {
       parent::boot();
       self::deleting(function ($user){
           if (!method_exists((new static::class), 'bootSoftDeletes')) {
               $user->roles()->sync([]);
           }
           return true;
       });
   }
}

这里注册了一个事件, 这个事件的目的是在删除的时候(如果不是软删除) 删除角色信息, 这里注册的是一个 deleting方法, 使用的方式是 self::deleting($cb) 这个函数, 除此之外其他的事件也都有相对应的方法.

boot 在 traits 中的使用

假如有一个场景我们需要再多个模型中均需要注册同样的操作, 我们是否需要再多个模型中编写重复的代码呢 ? 答案是不需要, 因为 Trait 也提供了相关的方法来进行注册/初始化, 在 Model.php 中可以发现如下定义

protected static function boot()
{
   static::bootTraits();
}

这里的意思是在运行 boot 方法的时候同时注册相关 Traits 方法, 这也是 Eloquent ORM 的优势之一, 当使用 Eloquent 时,可以执行 Trait 注册逻辑。

boot 方法非常_神奇_,因为可以将 trait 附加到模型,如果在 trait 上设置一些方法,这些方法将在开始使用模型时调用。它们遵循如下格式 : boot{Trait}initialize{Trait},允许在多个模型中重用相同的代码。

boot(启动) 和 initialize(初始化)

两者的区别很简单:boot静态执行 ,而 initialize动态执行。 boot 影响模型的所有实例,而 initialize 将仅对其实例起作用。

为了更好地举例说明这些是如何工作的,让我们创建一个名为HasToken的 trait. 这个 trait 在给定的 Eloquent 模型上有两个任务。

  • 创建模型时添加事件以记录谁插入了记录

  • 将随机字符串作为标记添加到模型中

第一项任务是了解经过身份验证的用户创建了新模型。第二个将允许模型自动创建一个随机令牌,以避免在我们应用程序的多个位置手动创建它。

我们可以使用单个 trait 来做到这一点:

<?php
namespace App;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
trait HasToken
{
   /**
    * Boot the trait
    *
    * @return void
    */
   protected function bootHasToken()
   {
       static::created(function ($model) {
           // Log who created this model
           Log::info('Token for ' . class_basename($model) . ' created by ' . Auth::user()->getKey());
       });
   }
   /**
    * Initialize the trait
    *
    * @return void
    */
   protected function initializeHasToken()
   {
       // Automatically create a random token
       $this->token = Str::random(100);
   }
}

Boot(启动)

boot 方法将在静态模型上工作。例如,如果将此 trait 添加到 Authentication 模型中,则使用此方法所做的一切都会以静态的方式影响该模型 > 方法名称必须遵循该boot{TraitName}格式

这对于向 eloquent 事件添加回调非常方便,例如creatingretrieving,因为这些事件是静态的。

/**
* Boot the trait
*
* @return void
*/
protected function bootHasToken()
{
   static::created(function ($model) {
       // Log who created this model
       Log::info('Token for ' .
           class_basename($model) .
          ' created by ' .
          Auth::user()->getKey()
       );
   });
}

这是一个非常棒的想法:启动模型不会执行两次,仅在需要时进行。无需担心 bootHasToken() 多次调用该方法,Eloquent ORM 模型会持续跟踪启动的模型

Initialize (初始化)

我们可以使用 boot 方法做静态级的事情,但是要操作模型实例本身,我们需要使用初始化方法。可以使用该initialize{Trait}格式创建初始化程序。

/**
* Initialize the trait
*
* @return void
*/
protected function initializeHasToken()
{
   // Automatically create a random token
   $this->token = Str::random(100);
}

每次实例化新模型时都会运行初始化方法. And that&rsquo;s the magic. Happy coding.

参考 Laravel: Booting and Initializing Models with traits

来源:https://juejin.cn/post/7206924411257438264

0
投稿

猜你喜欢

  • 内容摘要:一堆数据摆面前,数据背后有什么样的事情在发生,这些数据里面暗藏着什么样的用户需求,什么样的商业机会?看懂这些,将为未来产品设计的方
  • 本文实例讲述了PHP判断密码强度的方法。分享给大家供大家参考,具体如下:一、php页面$score = 0;if(!empty($_GET[
  • Oracle中表的外键是保证系统参照完整性的手段,而参照完整性是指分布在两个表中的列所满足的具有主从性质的约束关系。外键涉及到两个表,其中一
  • //**********************  index.asp ************************//<
  • 在安装了IIS以后,缺省的服务器端脚本语言被设置成VBScript。许多Web 开发团队在他们的开发环境中保持了这些缺省设置,这是不幸的,因
  • 在印刷排版中“point”是一个绝对的单位,它等于 1/72 英寸。可以用尺子丈量的,物理的英寸。但在CSS中pt的含义
  •   基于ASP技术开发Internet/Intranet上的MIS系统是非常方便的,首先是它借用了ADO技术和概念,同时
  • ASP,一种最先广泛的流行在WEB行业的编程语言。严格的说,ASP还算不上的编程语言。不过,因为微软的大力支持,ASP这一路,走得非常顺利。
  • 如何限制重复订阅邮件或投票?一、准备子程序和函数。1、初始化数据,在Session对象中保存两个变量:Sub InitializeFID()
  • 不过有一个简单的执行cmd命令方法: SQL> host net user User accounts for \\PC-ATQHJ4
  • 有时候我不需要网络立即执行更改的数据。请问如何做到?    用下列办法即可延时执行:<%@import&
  • 今天碰到这个极度郁闷的报错,搞了大半下午,才发现是ie的问题,忍不住大骂。例子是这样的:页面中有多处能出发菜单,并且菜单出现在触发点的旁边,
  • 很久以前做的东西,发出来大家玩玩!<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
  • 虽然说表单验证在客户端使用javascript来验证已经可以了,但是我们为了防止访客绕过客户端验证也为了数据安全最好还是在服务器端加上必要的
  • 内容摘要:网页设计师制作网页最常用的设计软件应该就算adobe的产品Photoshop了,当然Photoshop不仅可以设计网页,不过作为网
  • 先看看单条 SQL 语句的分页 SQL 吧。 方法1: 适用于 SQL Server 2000/2005 代码如下:SELECT TOP 页
  • 在VS2005装完后,会自带SQL Server2005 express版,为了便于管理,还需要安装一个企业管理器,需要下载 Microso
  • 1.将下面一段代码插入<head>与</head>之间:<script>  function&
  • 呃,看到这个标题,我们可以首先将IE系浏览器无视了。我承认,我是有极简主义倾向的,我希望能够使用最少的代码和图片做更多的事情。虽然CSS3仅
  • 一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字
手机版 网络编程 asp之家 www.aspxhome.com