当前位置:首页 > Lumen - 事件监听,一个非常有用的模式

Lumen - 事件监听,一个非常有用的模式

发布于 2018-04-23 阅读 555 次 框架 设计模式 PHP Lumen

事件(Event)

什么是事件呢?

它是一个动作
鼠标点击页面 - 点击事件
usb插入电脑 - 插入事件
打开电脑 - 开机事件

...

那我们在什么时候去使用事件呢?

场景

用户在注册网站后,我们需要发送一封验证邮件
用户在点击查看谋篇文章后,我们给这个文章的阅读数增加

...

这些我们都可以用事件来处理

使用

注册事件监听器

app/Providers/EventServiceProvider.php

namespace App\Providers;

use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * 注册事件,事件监听者.
     * 文章点击事件和监听者
     * @var array
     */
    protected $listen = [
        'App\Events\ArticleClickEvent' => [
            'App\Listeners\ArticleClickListener',
        ],
    ];
}

创建事件器

app/Events/ArticleClickEvent.php

namespace App\Events;


use App\Models\Article;
/**
 * ArticleClickEvent.php
 *
 * 文章事件
 *
 * @category  PHP
 * @package   w2le.com
 * @author    w2le.com
 */
class ArticleClickEvent
{
    /**
     * 创建一个文章对象属性
     *
     *
     * @var App\Models\Article
     */
    protected $article;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Article $article)
    {
        //把文章对象传入ArticleClickEvent中
        $this->article = $article;
    }
}

创建事件监听者

app/Listeners/ArticleClickListener.php

/**
 * ArticleClickListener.php
 *
 * 文章事件监听者
 *
 * @category  PHP
 * @package   w2le.com
 * @author    w2le.com
 */

namespace App\Listeners;

use App\Events\ArticleClickEvent;
class ArticleClickListener
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  ArticleClickEvent  $event
     * @return void
     */
    public function handle(ArticleClickEvent $event)
    {
        //获取ArticleClickEvent中我们传入的article对象
        $article = $event->article

        //有了article对象我们可以对文章进行操作
        //通过文章id更新文章阅读数
        updateArticleViews($article->id)
    }
}

使用事件

app/Http/Controllers/Article.php

//文章详情
public function index()
{
    do something
    ...
    //通过文章id获取文章
    $article = Article::find($id)

    //雇佣文章点击监听事件
    Event::fire(new ArticleClickEvent($article));
}

通过事件模式,我们可以把主业务跟支线业务逻辑做到很好的拆分
如上面提到的文章详情页面显示,我们只需要关心文章的展示。而文章其他相关的业务放到我们的监听事件里面来实行
这样不但简化了我们的controller逻辑,同时也极大的解耦了我们的业务

如果这时候在我们需要在文章查看后,需要给用户发一封邮件,你会怎么做呢?
是不是只需要在文章事件里增加一个邮件发送的处理就行了,这样还不需要修改controller中的代码