介绍
长久以来,面向对象程序确保了代码的灵活性。通过创建组织良好而分工明确的类,你的代码变得更加灵活,而其他开发者可以用子类扩展它们并修改基类的行为。但如果有人想要与其他已经有自己子类的开发者“共享这种改变”,那么代码继承便不再适用。
思考一个现实中的例子,你要在你的项目中提供一个插件系统。A插件要能添加方法,或者在别的方法被执行之前“做一些事”,而不去干涉其他插件。这并非单体继承所能解决的简单问题,即便PHP变得能够多重继承,还是会有很多欠点。
Symfony的EventDispatcher组件以一种简单高效的方式,实现了Mediator设计模式,令所有这些事成为可能,更令你的项目具备强大的灵活性。
详细介绍自行查看官方文档:Symfony / The EventDispatcher Component
常规事件监听
use Symfony\Component\EventDispatcher\EventDispatcher;
// 实例化派遣器
$dispatcher = new EventDispatcher();
// 添加监听事件
$dispatcher->addListener('order.creater', function($event, $eventName, $dispatcher){
echo "订单号是:{$event->orderNumber()}\n";
});
$dispatcher->addListener('order.creater', function($event, $eventName, $dispatcher){
echo "有一个新的订单被创建\n";
}, 10); // 第三个参数是优先级
$dispatcher->addListener('order.pay', function($event, $eventName, $dispatcher){
echo "订单已经付款\n";
});
// 创建事件
// use Symfony\Component\EventDispatcher\Event; // @deprecated since Symfony 4.3, use "Symfony\Contracts\EventDispatcher\Event" instead
use Symfony\Contracts\EventDispatcher\Event;
class OrderEvent extends Event
{
protected $order;
public function __construct($order)
{
$this->order = $order;
}
public function orderNumber()
{
return $this->order;
}
}
// 派遣事件
$dispatcher->dispatch(new OrderEvent('1234567890'), 'order.creater');
$dispatcher->dispatch(new OrderEvent('1234567890'), 'order.pay');
// 输出
# 有一个新的订单被创建
# 订单号是:1234567890
# 订单已经付款
使用事件订阅器
namespace Acme\Store\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Acme\Store\Event\OrderPlacedEvent;
// 创建一个订阅器,必须继承 EventSubscriberInterface 接口
class StoreSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
KernelEvents::RESPONSE => array(
array('onKernelResponsePre', 10),
array('onKernelResponsePost', -10),
),
OrderEvent::NAME => 'onStoreOrder',
);
}
public function onKernelResponsePre(FilterResponseEvent $event)
{
// ...
}
public function onKernelResponsePost(FilterResponseEvent $event)
{
// ...
}
public function onStoreOrder(OrderEvent $event)
{
echo $event->orderNumber();
}
}
// 创建事件
use Symfony\Contracts\EventDispatcher\Event;
class OrderEvent extends Event
{
const NAME = 'order.create';
protected $order;
public function __construct($order)
{
$this->order = $order;
}
public function orderNumber()
{
return $this->order;
}
}
// 实例化派遣器
$dispatcher = new EventDispatcher();
// 添加事件订阅器
$dispatcher->addSubscriber(new StoreSubscriber());
// 派遣事件
$dispatcher->dispatch(new OrderEvent('1234567890'), OrderEvent::NAME);
// 输出:
# 1234567890