前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[译]Laravel 5.0 之事件及处理程序

[译]Laravel 5.0 之事件及处理程序

作者头像
小李刀刀
发布2018-03-02 17:04:25
1.2K0
发布2018-03-02 17:04:25
举报
文章被收录于专栏:PHP 开发

本文译自 Matt Stauffer系列文章.


提示:如果你还没有看过 Laravel 5.0 之命令及处理程序 这篇文章,建议先看一下。它包括了本文所需的背景知识。

借助 Laravel 5 的命令(及命令处理程序),你可以通过封装的方式非常简单、直接地向系统发出命令。DoThis.HandleACommandThatIsTellingMeToDoThis, 它是命令式的,告诉系统要做什么事。

但有时候,不管是在命令结果中,还是在其它的上下文中,我们需要发出更抽象的通知。比如在 Laravel 4 中,可以直接以事件名称的字符串来触发事件(而不是像上面那样通过对象和方法):

代码语言:javascript
复制
$response = Event::fire('auth.login', array($user));

这行代码向整个应用发出一条通知:“有人登陆了,这是用户信息”。它是知会式的,只是知会事件发生比提供相关信息。如果你熟悉“发布/订阅”概念的话,这就是“事件”机制要处理的。

在 Laravel 5 中,事件系统已经得到了升级,看上去与上一篇文章中介绍过的命令系统有几分相似。在升级后的事件系统中,不是基于字符串来标识事件(比如 "auth.login"),而是创建一个 PHP 对象,并发布它。

示例

接下来,直接以例子来做说明:

生成事件

代码语言:javascript
复制
$ php artisan make:event ThingWasDone

... 这行命令会生成下面的代码:

代码语言:javascript
复制
namespace SaveMyProposals\Events;

use SaveMyProposals\Events\Event;

use Illuminate\Queue\SerializesModels;

class ThingWasDone extends Event {

    use SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

}

你可以给构造函数添加参数并把参数值绑定到类的属性值,通过这样的方式为这个类提供额外的数据。

生成事件处理程序

执行命令:

代码语言:javascript
复制
$ php artisan handler:event SendMailInSomeParticularContext --event="ThingWasDone"

这行代码会生成下面的代码:

代码语言:javascript
复制
namespace SaveMyProposals\Handlers\Events;

use SaveMyProposals\Events\ThingWasDone;

use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;

class SendMailInSomeParticularContext {

    /**
     * Create the event handler.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  ThingWasDone  $event
     * @return void
     */
    public function handle(ThingWasDone $event)
    {
        //
    }

}

需要注意的一点是,生成的代码中,已经为 handle 方法指定了一个带有类型约束的 ThingWasDone $event 参数。不管是构造函数还是 event 方法,你都可以借助依赖注入来提供任何你需要的工具或对象。

绑定事件

在上一个步骤中我们创建了一个事件及其处理程序,但仅仅是创建,并没有通知事件总线(bus)我们刚才创建的事件和处理程序是配对的。所以接下来还需要在 app\Providers\EventServiceProvider 中绑定它们的监听关系,可以在 $listen 属性中做这件事:

代码语言:javascript
复制
// app\Providers\EventServiceProvider
    $listen = [
        ThingWasDone::class => [
            SendMailInSomeParticularContext::class,
            SaveSomeRecordInSomeOtherContext::class,
            DoSomethingElseInResponseToThingBeingDone::class
        ]
    ];

如你所见,通过 ::class 得到一个代表事件类名的字符串作为 key,然后在值数组中添加监听器(也是通过 ::class)。

“预备...瞄准...开火(::fire)”

好了,一切准备就绪,接下来就是触发该事件了。要注意的是这里只有简单的 PHP 类,所以你可以手动实例化事件,实例化事件对应的处理程序,然后把事件传递给处理程序。但那当然不是 Laravel 的思路, Laravel 提供了事件总线让以上这一系列的工作更简单,更具有一致性和全局性:

代码语言:javascript
复制
\Event::fire(new ThingWasDone($param1, $param2));

就这么简单!

ShouldBeQueued

与命令系统的机制一样,你可以让你的事件实现 Illuminate\Contracts\Queue\ShouldBeQueued 接口,从而使事件处理程序被加入到队列中异步执行;也可以给你的事件处理程序加上 Illuminate\Queue\InteractsWithQueue 的 trait,使事件处理程序的 handle 方法变得容易从外部访问,从而使事件处理程序可以和事件队列进行交互。比如在队列中删除当前的任务。

SerializesModels trait

还是与命令一样的,如果你需要在事件中用到某个 Eloquent 模型,你可以在事件类的代码顶部包含 SerializesModels 这个 trait。在本文写作时,生成的时间代码实际上已经默认包含了这部分。

写在最后

就这么多了。只要你理解了 Laravel 5 的命令和处理程序,掌握事件处理机制就是一件非常容易的事了。触发系统向整个应用发出通知说某个事件发生了,而不是要求系统执行某些操作。但本质上它们都是封装的信息和目的。它们可以互相配合使用,结果会更棒!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 示例
    • 生成事件
      • 生成事件处理程序
        • 绑定事件
          • “预备...瞄准...开火(::fire)”
          • ShouldBeQueued
          • SerializesModels trait
          • 写在最后
          相关产品与服务
          事件总线
          腾讯云事件总线(EventBridge)是一款安全,稳定,高效的云上事件连接器,作为流数据和事件的自动收集、处理、分发管道,通过可视化的配置,实现事件源(例如:Kafka,审计,数据库等)和目标对象(例如:CLS,SCF等)的快速连接,当前 EventBridge 已接入 100+ 云上服务,助力分布式事件驱动架构的快速构建。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档