Laravel 模型事件 - 我对它们的去向有点困惑
所以我认为一个好的 Laravel 应用程序应该是非常模型驱动和事件驱动的.
So the way I see it is that a good Laravel application should be very model- and event-driven.
我有一个名为 Article
的模型.我希望在发生以下事件时发送电子邮件警报:
I have a Model called Article
. I wish to send email alerts when the following events happen:
- 何时创建文章
- 文章更新时
- 当文章被删除时
文档说我可以使用模型事件并在 <AppProvidersEventServiceProvider
的code>boot()函数.
The docs say I can use Model Events and register them within the boot()
function of AppProvidersEventServiceProvider
.
但这让我很困惑,因为...
But this is confusing me because...
- 当我添加其他模型(如
Comment
或Author
)时,会发生什么,这些模型需要所有自己的模型事件的完整集合?EventServiceProvider
的单个boot()
函数会非常庞大吗? - Laravel 的其他"事件的目的是什么?如果实际上我的事件只会响应模型 CRUD 操作,为什么我还需要使用它们?
- What happens when I add further models like
Comment
orAuthor
that need full sets of all their own Model Events? Will the singleboot()
function ofEventServiceProvider
just be absolutely huge? - What is the purpose of Laravel's 'other' Events? Why would I ever need to use them if realistically my events will only respond to Model CRUD actions?
我是 Laravel 的初学者,来自 CodeIgniter,所以我试图围绕正确的 Laravel 做事方式进行思考.感谢您的建议!
I am a beginner at Laravel, having come from CodeIgniter, so trying to wrap my head around the proper Laravel way of doing things. Thanks for your advice!
推荐答案
最近我在我的 Laravel 5 项目之一中遇到了同样的问题,我不得不在其中记录所有模型事件.我决定使用 Traits
.我创建了 ModelEventLogger
Trait 并简单地用于所有需要记录的模型类.我将根据您的需要更改它,如下所示.
Recently I came to same problem in one of my Laravel 5 project, where I had to log all Model Events. I decided to use Traits
. I created ModelEventLogger
Trait and simply used in all Model class which needed to be logged. I am going to change it as per your need Which is given below.
<?php
namespace AppTraits;
use IlluminateDatabaseEloquentModel;
use IlluminateSupportFacadesEvent;
/**
* Class ModelEventThrower
* @package AppTraits
*
* Automatically throw Add, Update, Delete events of Model.
*/
trait ModelEventThrower {
/**
* Automatically boot with Model, and register Events handler.
*/
protected static function bootModelEventThrower()
{
foreach (static::getModelEvents() as $eventName) {
static::$eventName(function (Model $model) use ($eventName) {
try {
$reflect = new ReflectionClass($model);
Event::fire(strtolower($reflect->getShortName()).'.'.$eventName, $model);
} catch (Exception $e) {
return true;
}
});
}
}
/**
* Set the default events to be recorded if the $recordEvents
* property does not exist on the model.
*
* @return array
*/
protected static function getModelEvents()
{
if (isset(static::$recordEvents)) {
return static::$recordEvents;
}
return [
'created',
'updated',
'deleted',
];
}
}
现在您可以在要为其抛出事件的任何模型中使用此特征.在您的情况下 Article
模型.
Now you can use this trait in any Model you want to throw events for. In your case in Article
Model.
<?php namespace App;
use AppTraitsModelEventThrower;
use IlluminateDatabaseEloquentModel;
class Article extends Model {
use ModelEventThrower;
//Just in case you want specific events to be fired for Article model
//uncomment following line of code
// protected static $recordEvents = ['created'];
}
现在在您的 app/Providers/EventServiceProvider.php
中,在 boot()
方法中为 Article
注册事件处理程序.
Now in your app/Providers/EventServiceProvider.php
, in boot()
method register Event Handler for Article
.
public function boot(DispatcherContract $events)
{
parent::boot($events);
$events->subscribe('AppHandlersEventsArticleEventHandler');
}
现在在app/Handlers/Events
目录下创建ArticleEventHandler
类,
<?php namespace AppHandlersEvents;
use AppArticle;
class ArticleEventHandler{
/**
* Create the event handler.
*
* @return AppHandlersEventsArticleEventHandler
*/
public function __construct()
{
//
}
/**
* Handle article.created event
*/
public function created(Article $article)
{
//Implement logic
}
/**
* Handle article.updated event
*/
public function updated(Article $article)
{
//Implement logic
}
/**
* Handle article.deleted event
*/
public function deleted(Article $article)
{
//Implement logic
}
/**
* @param $events
*/
public function subscribe($events)
{
$events->listen('article.created',
'AppHandlersEventsArticleEventHandler@created');
$events->listen('article.updated',
'AppHandlersEventsArticleEventHandler@updated');
$events->listen('article.deleted',
'AppHandlersEventsArticleEventHandler@deleted');
}
}
正如您从不同的答案中看到的,来自不同的用户,处理模型事件的方法不止一种.还有自定义事件,可以在Events文件夹中创建,可以在Handler文件夹中处理,可以从不同的地方分派.希望能帮到你.
As you can see from different answers, from different Users, there are more than 1 way of handling Model Events. There are also Custom events That can be created in Events folder and can be handled in Handler folder and can be dispatched from different places. I hope it helps.
相关文章