ZF2 事件触发
ZF2 events triggering
我遇到以下情况:
我触发事件的应用程序模块之一,在同一个模块中我创建了一个事件侦听器,它通过共享事件管理器系统侦听该触发器,通过这一步一切正常,我试图在不同的模块中创建更多侦听器事件,它们也工作正常,调用了所有侦听器。
我想要的是拥有一个可以从多个地方触发相同事件的系统。例如,我创建了一个发送邮件模块,其中我将有一个侦听器,它将侦听 "sendMail" 触发器并执行一些操作,是否可以从不同的模块触发相同的事件?
我试图从 2 个地方触发相同的事件,但共享事件的附加方法将第一个参数作为调用者的 ID class,即 class 的 ID触发事件,这样我只能从指定的 class 触发事件。
我想要的是从任意多个地方触发该事件。
非常感谢大家!
为什么要使用共享事件管理器?
如果您为 "operations" 创建一个服务,您可以初始化一个
新的事件管理器,您可以在其中随心所欲地附加事件。
而且 ofc 从任何地方扣动扳机。
我还建议您附上一个事件聚合,以便于代码审查和提高可读性
如果您使用 Zend\EventManager\EventManagerAwareTrait
或从 ZfcBase\EventManager\EventProvider
继承,您可以提供自己的事件标识符来收听。
如果您在此处查看 EventManagerAwareTrait::setEventManager()
方法中包含的代码
还有ZfcBase\EventManager\EventProvider::setEventManager()
这里
https://github.com/ZF-Commons/ZfcBase/blob/master/src/ZfcBase/EventManager/EventProvider.php#L26-L37
您会注意到该方法会自动查找名为 $eventIdentifier
的 属性,期望它是一个字符串或字符串数组,如果存在,将与默认标识符合并FQCN 和 class 名称。
所以基本上,您可以通过简单地向事件管理器添加 属性 来添加自己的标识符 classes(触发事件的事件)
<?php
namespace Somenamespace;
use Zend\EventManager\EventManagerAwareInterface;
class EventTriggeringClass implements EventManagerAwareInterface
{
use \Zend\EventManager\EventManagerAwareTrait;
protected $eventIdentifier = 'SendMailIdentifier';
}
和
namespace Someothernamespace;
use Zend\EventManager\EventManagerAwareInterface;
class SomeOtherEventTriggeringClass implements EventManagerAwareInterface
{
use \Zend\EventManager\EventManagerAwareTrait;
protected $eventIdentifier = 'SendMailIdentifier';
}
您的听众现在只需附加到 SendMailIdentifier
,而不是针对任何特定 class 的 FQCN。
当然,您也可以在必要时附加到 FQCN,因为它是通过 setEventManager 方法合并的标识符之一。
共享事件管理器允许附加到通配符,因此要附加到 foo
事件,无论其来源如何,您都可以这样做:
$sharedEventManager->attach('*', 'foo', ...);
有关通配符的更多详细信息,请查看 EventManager 文档页面:http://framework.zend.com/manual/current/en/tutorials/tutorial.eventmanager.html#wildcards
我遇到以下情况: 我触发事件的应用程序模块之一,在同一个模块中我创建了一个事件侦听器,它通过共享事件管理器系统侦听该触发器,通过这一步一切正常,我试图在不同的模块中创建更多侦听器事件,它们也工作正常,调用了所有侦听器。
我想要的是拥有一个可以从多个地方触发相同事件的系统。例如,我创建了一个发送邮件模块,其中我将有一个侦听器,它将侦听 "sendMail" 触发器并执行一些操作,是否可以从不同的模块触发相同的事件?
我试图从 2 个地方触发相同的事件,但共享事件的附加方法将第一个参数作为调用者的 ID class,即 class 的 ID触发事件,这样我只能从指定的 class 触发事件。 我想要的是从任意多个地方触发该事件。 非常感谢大家!
为什么要使用共享事件管理器?
如果您为 "operations" 创建一个服务,您可以初始化一个 新的事件管理器,您可以在其中随心所欲地附加事件。 而且 ofc 从任何地方扣动扳机。
我还建议您附上一个事件聚合,以便于代码审查和提高可读性
如果您使用 Zend\EventManager\EventManagerAwareTrait
或从 ZfcBase\EventManager\EventProvider
继承,您可以提供自己的事件标识符来收听。
如果您在此处查看 EventManagerAwareTrait::setEventManager()
方法中包含的代码
还有ZfcBase\EventManager\EventProvider::setEventManager()
这里
https://github.com/ZF-Commons/ZfcBase/blob/master/src/ZfcBase/EventManager/EventProvider.php#L26-L37
您会注意到该方法会自动查找名为 $eventIdentifier
的 属性,期望它是一个字符串或字符串数组,如果存在,将与默认标识符合并FQCN 和 class 名称。
所以基本上,您可以通过简单地向事件管理器添加 属性 来添加自己的标识符 classes(触发事件的事件)
<?php
namespace Somenamespace;
use Zend\EventManager\EventManagerAwareInterface;
class EventTriggeringClass implements EventManagerAwareInterface
{
use \Zend\EventManager\EventManagerAwareTrait;
protected $eventIdentifier = 'SendMailIdentifier';
}
和
namespace Someothernamespace;
use Zend\EventManager\EventManagerAwareInterface;
class SomeOtherEventTriggeringClass implements EventManagerAwareInterface
{
use \Zend\EventManager\EventManagerAwareTrait;
protected $eventIdentifier = 'SendMailIdentifier';
}
您的听众现在只需附加到 SendMailIdentifier
,而不是针对任何特定 class 的 FQCN。
当然,您也可以在必要时附加到 FQCN,因为它是通过 setEventManager 方法合并的标识符之一。
共享事件管理器允许附加到通配符,因此要附加到 foo
事件,无论其来源如何,您都可以这样做:
$sharedEventManager->attach('*', 'foo', ...);
有关通配符的更多详细信息,请查看 EventManager 文档页面:http://framework.zend.com/manual/current/en/tutorials/tutorial.eventmanager.html#wildcards