So the way I see it is that a good Laravel application should be very model- and event-driven.

I have a Model called Article. I wish to send email alerts when the following events happen:

  • 创建文章时
  • 当文章更新时
  • When an Article is deleted

The docs say I can use Model Events and register them within the boot() function of App\Providers\EventServiceProvider.

But this is confusing me because...

  • 当我添加更多的模型(如CommentAuthor)时会发生什么,它们需要所有自己的模型事件的完整集合?EventServiceProvider的单个boot()功能会绝对巨大吗?
  • 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?

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并简单地用于所有需要记录的模型类.我将根据您的需求进行更改,如下所示.

<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Event;

/**
 * Class ModelEventThrower 
 * @package App\Traits
 *
 *  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型的.

<?php namespace App;

use App\Traits\ModelEventThrower;
use Illuminate\Database\Eloquent\Model;

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'];

}

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('App\Handlers\Events\ArticleEventHandler');
 }

现在在app/Handlers/Events目录下创建ArticleEventHandler类,如下所示.

<?php namespace App\Handlers\Events;

use App\Article;

class ArticleEventHandler{

    /**
     * Create the event handler.
     *
     * @return \App\Handlers\Events\ArticleEventHandler
     */
    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',
            'App\Handlers\Events\ArticleEventHandler@created');
     $events->listen('article.updated',
            'App\Handlers\Events\ArticleEventHandler@updated');
     $events->listen('article.deleted',
            'App\Handlers\Events\ArticleEventHandler@deleted');
 }

}

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.

Laravel相关问答推荐

如何更改LIVE上的Filament占位符内容?

如何在 laravel 中为另一个用户 session()->forget('cart')?

在 laravel 中查询此类数据的最佳做法是什么?

如何在 Laravel 5 中添加我自己的自定义类?

Laravel 5.4 - 如何为同一个自定义验证规则使用多个错误消息

用 laravel 表单确认删除?

有条件的Eager加载

Laravel Input:all() 忽略禁用的输入

在 Laravel 中无效后防止重定向到主页

在 Laravel 5.4 中将中间件应用于除 `setup/*` 之外的所有路由

WhereNotExists Laravel Eloquent

Laravel 和 PHPStorm 项目的 gitignore 中包含什么?

控制器外部的 Laravel 访问请求对象

日期验证 - 如何本地化/翻译字符串今天和明天

Laravel 存储链接不适用于生产

Laravel 如何具体构建和判断 CSRF 令牌?

Laravel 如何从子域 URL 中删除api前缀

在 Laravel 5.4 中将文件存储在公共目录和存储中的区别

如何在 Laravel 5 中验证 RESTful API?

如何在不要求用户登录 Laravel 的情况下验证Electron邮件