[译]Laravel 5.0 之事件及处理程序
本文译自 Matt Stauffer 的系列文章.
提示:如果你还没有看过 Laravel 5.0 之命令及处理程序 这篇文章,建议先看一下。它包括了本文所需的背景知识。
借助 Laravel 5 的命令(及命令处理程序),你可以通过封装的方式非常简单、直接地向系统发出命令。DoThis.HandleACommandThatIsTellingMeToDoThis
, 它是命令式的,告诉系统要做什么事。
但有时候,不管是在命令结果中,还是在其它的上下文中,我们需要发出更抽象的通知。比如在 Laravel 4 中,可以直接以事件名称的字符串来触发事件(而不是像上面那样通过对象和方法):
$response = Event::fire('auth.login', array($user));
这行代码向整个应用发出一条通知:“有人登陆了,这是用户信息”。它是知会式的,只是知会事件发生比提供相关信息。如果你熟悉“发布/订阅”概念的话,这就是“事件”机制要处理的。
在 Laravel 5 中,事件系统已经得到了升级,看上去与上一篇文章中介绍过的命令系统有几分相似。在升级后的事件系统中,不是基于字符串来标识事件(比如 "auth.login"),而是创建一个 PHP 对象,并发布它。
示例
接下来,直接以例子来做说明:
生成事件
$ php artisan make:event ThingWasDone
... 这行命令会生成下面的代码:
namespace SaveMyProposalsEvents;
use SaveMyProposalsEventsEvent;
use IlluminateQueueSerializesModels;
class ThingWasDone extends Event {
use SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}
}
你可以给构造函数添加参数并把参数值绑定到类的属性值,通过这样的方式为这个类提供额外的数据。
生成事件处理程序
执行命令:
$ php artisan handler:event SendMailInSomeParticularContext --event="ThingWasDone"
这行代码会生成下面的代码:
namespace SaveMyProposalsHandlersEvents;
use SaveMyProposalsEventsThingWasDone;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldBeQueued;
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)我们刚才创建的事件和处理程序是配对的。所以接下来还需要在 appProvidersEventServiceProvider
中绑定它们的监听关系,可以在 $listen
属性中做这件事:
// appProvidersEventServiceProvider
$listen = [
ThingWasDone::class => [
SendMailInSomeParticularContext::class,
SaveSomeRecordInSomeOtherContext::class,
DoSomethingElseInResponseToThingBeingDone::class
]
];
如你所见,通过 ::class
得到一个代表事件类名的字符串作为 key,然后在值数组中添加监听器(也是通过 ::class
)。
“预备...瞄准...开火(::fire)”
好了,一切准备就绪,接下来就是触发该事件了。要注意的是这里只有简单的 PHP 类,所以你可以手动实例化事件,实例化事件对应的处理程序,然后把事件传递给处理程序。但那当然不是 Laravel 的思路, Laravel 提供了事件总线让以上这一系列的工作更简单,更具有一致性和全局性:
Event::fire(new ThingWasDone($param1, $param2));
就这么简单!
ShouldBeQueued
与命令系统的机制一样,你可以让你的事件实现 IlluminateContractsQueueShouldBeQueued
接口,从而使事件处理程序被加入到队列中异步执行;也可以给你的事件处理程序加上 IlluminateQueueInteractsWithQueue
的 trait,使事件处理程序的 handle
方法变得容易从外部访问,从而使事件处理程序可以和事件队列进行交互。比如在队列中删除当前的任务。
SerializesModels trait
还是与命令一样的,如果你需要在事件中用到某个 Eloquent 模型,你可以在事件类的代码顶部包含 SerializesModels
这个 trait。在本文写作时,生成的时间代码实际上已经默认包含了这部分。
写在最后
就这么多了。只要你理解了 Laravel 5 的命令和处理程序,掌握事件处理机制就是一件非常容易的事了。触发系统向整个应用发出通知说某个事件发生了,而不是要求系统执行某些操作。但本质上它们都是封装的信息和目的。它们可以互相配合使用,结果会更棒!
- 【网络编程系列】一:字节顺序的大端与小端表示法
- Linux下的make命令用法
- 增量数据丢失的原因分析(三)(r8笔记第91天)
- JS之浏览器对象BOM
- 超清晰的makefile解释、编写与示例
- 一个简单的sql审核案例 (r8笔记第90天)
- Linux wait() 和 waitpid()函数介绍
- #if和#ifdef的区别
- 一个MySQL优化案例的初步思路(r8笔记第87天)
- 一条直线上N个线段所覆盖的总长度
- Go 语言 数据库操作之插入数据实现
- (摘抄)GO语言中template的用法
- 大数据时代的技术hive:hive介绍
- hadoop2.6分布式部署时 livenodes等于1的原因
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC