当前位置: 首页 > 后端技术 > PHP

Laravel模型事件入门

时间:2023-03-29 19:34:20 PHP

Laravel模型事件允许您监听模型生命周期中的多个关键点,甚至可以防止模型被保存或删除。LaravelModelEvents文档概述了如何使用钩子将相应的事件与相关的事件类型相关联,但本文主要关注构建和设置事件和监听器,以及一些额外的细节。事件概述Eloquent有许多事件,允许您将它们连接起来并为您的模型添加自定义功能。该模型从以下事件开始:retrievedcreatingcreatedupdatingupdatedsavedsaveddeletingdeletedrestoringrestored从文档中,我们可以了解它们是如何实现的。您还可以进入Model的基类以查看它们是如何实现的:当数据库检索到现有模型时,将触发检索到的事件。creating和created事件将在第一次保存新模型时触发。如果在数据库中已存在的模型上调用save方法,将触发更新/更新事件。在这两种情况下,saving/saved事件都会触发。该文档很好地概述了模型事件并解释了如何使用钩子来关联事件,但是如果您是初学者,或者不熟悉如何使用钩子将事件侦听器与这些自定义模型事件相关联,请继续阅读本文文章。注册事件为了在你的模型中连接一个事件,你需要做的第一件事是使用$dispatchesEvents属性注册事件对象,它最终将通过HasEvents::fireCustomModelEvent()方法触发,该方法将通过fireModelEvent()方法被调用。原始的fireCustomModelEvent()方法如下所示:/***为给定事件触发自定义模型。**@paramstring$event*@paramstring$method*@returnmixed|null*/protectedfunctionfireCustomModelEvent($event,$method){if(!isset($this->dispatchesEvents[$event])){返回;$result=static::$dispatcher->$method(new$this->dispatchesEvents[$event]($this));如果(!is_null($result)){返回$result;}}一些事件,比如delete会检测事件是否会返回false并退出操作。例如,您可以使用此挂钩进行一些检测,还可以防止创建或删除用户。以App\User模型为例,以下是配置模型事件的方法:您可以使用artisanmake:event命令为您创建此事件,但基本上这将是您最终得到的:user=$user;我们的事件提供了一个公共的$user属性,因此您可以在保存事件期间访问User模型实例。接下来我们需要做的就是为此事件设置一个实际的侦听器。我们设置模型的触发时机。当用户模型触发保存事件时,监听器将被调用。创建一个事件侦听器现在,我们定义用户模型并注册一个事件侦听器以触发保存事件。尽管我能够使用模型观察器快速完成此操作,但是,我想指导您为单个事件触发配置事件侦听器。事件监听器与其他Laravel事件监听器一样,handle()方法将接收App\Events\UserSaving事件类的实例。您可以手动创建它,或使用phpartisanmake:listener命令。无论哪种方式,您都将像这样创建一个侦听器类:info($event->user);我刚刚添加了一个日志记录调用,以方便检查传递给侦听器的模型。为此,我们还需要在EventServiceProvider::$listen属性中注册监听器:extendsServiceProvider{/***应用程序的事件侦听器。**@vararray*/protected$listen=[\App\Events\UserSaving::class=>[\App\Listeners\UserSaving::class,],];//...}现在,当模型调用保存事件时,我们注册的事件监听器也会被触发并执行。试试事件监听我们可以通过tinkersession快速生成事件监听代码:phpartisantinker>>>factory(\App\User::class)->create();=>App\User{#794name:"AidenCremin",email:"josie05@example.com",updated_at:"2018-03-1503:57:18",created_at:"2018-03-1503:57:18",id:2,}如果你有正确注册事件和侦听器后,您应该在laravel.log文件中看到模型的JSON表示:[2018-03-1503:57:18]local.INFO:{"name":"AidenCremin","email":"josie05@example.com"}需要注意的一件事是模型此时没有created_at或updated_at属性。如果在模型上再次调用save(),日志中将有一条带有时间戳的新记录,因为保存事件会在新创建或现有记录上触发:>>>$u=factory(\App\User::class)->create();=>App\User{#741name:"EloisaHirthe",email:"gottlieb.itzel@example.com",updated_at:"2018-03-1503:59:37",created_at:"2018-03-1503:59:37",id:3,}>>>$u->save();=>true>>>stopasaveoperationsomemodeleventsare允许您执行阻塞操作。举个荒谬的例子,假设我们不允许任何User模型将其属性$user->name的内容保存为Paul:/***Handleevents。**@param\App\Events\UserSaving$event*@returnmixed*/publicfunctionhandle(UserSaving$event){if(stripos($event->user->name,'paul')!==false){返回假;在Eloquent的Model::save()方法中,会根据事件监听的返回结果判断是否停止保存:publicfunctionsave(array$options=[]){$query=$this->newQueryWithoutScopes();//如果“saving”事件返回false,我们中止保存并返回//false,表示保存失败。这为服务侦听器提供了机会//??在验证失败或发生任何其他情况时取消保存操作。如果($this->fireModelEvent('saving')===false){returnfalse;}这个save()就是一个很好的例子,它告诉你如何自定义模型生命周期中的事件,以及被动执行日志数据记录或任务调度。使用观察者如果您正在监听多个事件,您可能会发现使用观察者类来存储按类型分组的事件会更方便。这是一个雄辩的观察者示例: