joomla-x / event
Joomla 事件包
Requires
- php: >=5.3.10|>=7.0
Requires (Dev)
- phpunit/phpunit: ~4.8|~5.0
- squizlabs/php_codesniffer: 1.*
This package is auto-updated.
Last update: 2024-08-29 04:48:42 UTC
README
事件包提供了构建事件系统的基础,并支持优先级监听器。
事件
示例
事件有一个名称,并且可以传输参数。
namespace MyApp; use Joomla\Event\Event; // Creating an Event called "onSomething". $event = new Event('onSomething'); // Adding an argument named "foo" with value "bar". $event->addArgument('foo', 'bar'); // Setting the "foo" argument with a new value. $event->setArgument('foo', new \stdClass); // Getting the "foo" argument value. $foo = $event->getArgument('foo');
其传播可以被阻止
$event->stop();
事件监听器
事件监听器可以监听一个或多个事件。
您可以创建两种类型的监听器:使用类或闭包(匿名函数)。
函数必须将 EventInterface(或其子类)作为唯一的参数。
类
监听器监听与其实例方法名称匹配的事件。
namespace MyApp; use Joomla\Event\EventInterface; /** * A listener listening to content manipulation events. */ class ContentListener { /** * Listens to the onBeforeContentSave event. */ public function onBeforeContentSave(EventInterface $event) { // Do something with the event, you might want to inspect its arguments. } /** * Listens to the onAfterContentSave event. */ public function onAfterContentSave(EventInterface $event) { } }
闭包
闭包可以监听任何事件,但在将其添加到分发器(见下文)时必须声明。
namespace MyApp; use Joomla\Event\EventInterface; $listener = function (EventInterface $event) { // Do something with the event, you might want to inspect its arguments. };
分发器
分发器是事件系统的中心点,它管理事件的注册、监听器的注册以及事件的触发。
注册对象监听器
按照上面的示例,您可以注册 ContentListener
到分发器
namespace MyApp; use Joomla\Event\Dispatcher; // Creating a dispatcher. $dispatcher = new Dispatcher; /** * Adding the ContentListener to the Dispatcher. * By default, it will be registered to all events matching it's method names. * So, it will be registered to the onBeforeContentSave and onAfterContentSave events. */ $dispatcher->addListener(new ContentListener);
如果对象包含其他不应注册的方法,您需要显式列出要注册的事件。例如
$dispatcher->addListener( new ContentListener, array( 'onBeforeContentSave' => Priority::NORMAL, 'onAfterContentSave' => Priority::NORMAL, ) ); // Alternatively, include a helper method: $listener = new ContentListener; $dispatcher->addListener($listener, $listener->getEvents());
注册闭包监听器
namespace MyApp; use Joomla\Event\Dispatcher; use Joomla\Event\Priority; // Of course, it shouldn't be empty. $listener = function (EventInterface $event) { }; $dispatcher = new Dispatcher; /** * Adding a Closure Listener to the Dispatcher. * You must specify the event name and the priority of the listener. * Here, we register it for the onContentSave event with a normal Priority. */ $dispatcher->addListener( $listener, array('onContentSave' => Priority::NORMAL) );
如您所见,您可以为特定事件指定监听器的优先级。您也可以为“对象”监听器这样做。
过滤监听器
已弃用
监听器类可能会变得相当复杂,并可能支持除了事件处理所需之外的其他公共方法。可以使用 setListenerFilter
方法设置一个正则表达式,用于检查作为监听器添加的对象的方法名称。
// Ensure the dispatcher only registers "on*" methods. $dispatcher->setListenerFilter('^on');
带优先级的注册
namespace MyApp; use Joomla\Event\Dispatcher; use Joomla\Event\Priority; /** * Adding the ContentListener to the Dispatcher. * It will be registered with a high priority for the onBeforeContentSave, and * an "Above normal" priority for the onAfterContentSave event. */ $dispatcher->addListener( new ContentListener, array( 'onBeforeContentSave' => Priority::HIGH, 'onAfterContentSave' => Priority::ABOVE_NORMAL ) );
默认优先级是 Priority::NORMAL
。
当您添加未指定事件名称的“对象”监听器时,它将使用NORMAL优先级注册到所有事件。
/** * Here, it won't be registered to the onAfterContentSave event because * it is not specified. * * If you specify a priority for an Event, * then you must specify the priority for all Events. * * It is good pracctice to do so, it will avoid to register the listener * to "useless" events and by consequence save a bit of memory. */ $dispatcher->addListener( new ContentListener, array('onBeforeContentSave' => Priority::NORMAL) );
如果某些监听器对给定事件的优先级相同,它们将按添加到分发器的顺序被调用。
注册事件
如果您需要自定义事件,则可以将事件注册到分发器。
namespace MyApp; use Joomla\Event\Dispatcher; use Joomla\Event\Event; // Creating an event with a "foo" argument. $event = new Event('onBeforeContentSave'); $event->setArgument('foo', 'bar'); // Registering the event to the Dispatcher. $dispatcher = new Dispatcher; $dispatcher->addEvent($event);
默认情况下,在触发事件时,将创建不带参数的 Event
对象。
触发事件
一旦注册了您的监听器(以及最终将事件添加到分发器),您就可以触发事件。
监听器将按照它们对该事件的优先级顺序在队列中调用。
// Triggering the onAfterSomething Event. $dispatcher->triggerEvent('onAfterSomething');
如果您注册了一个具有 onAfterSomething
名称的事件对象,则它将传递给所有监听器,而不是默认的事件。
您还可以在触发时传递自定义事件
namespace MyApp; use Joomla\Event\Dispatcher; use Joomla\Event\Event; // Creating an event called "onAfterSomething" with a "foo" argument. $event = new Event('onAfterSomething'); $event->setArgument('foo', 'bar'); $dispatcher = new Dispatcher; // Triggering the onAfterSomething Event. $dispatcher->triggerEvent($event);
如果您已经使用 addEvent
添加了具有 onAfterSomething 名称的事件,则传递给 triggerEvent
方法的事件将被选择。
阻止传播
如上所述,如果您正在监听支持传播的事件,则可以停止事件传播,这是 Event
类的情况。
namespace MyApp; use Joomla\Event\Event; class ContentListener { public function onBeforeContentSave(Event $event) { // Stopping the Event propagation. $event->stop(); } }
在停止事件传播时,队列中的下一个监听器不会被调用。
可观察的类
可观察的类依赖于分发器,并且它们可能实现了 DispatcherAwareInterface
接口。
模型类的示例
namespace MyApp; use Joomla\Event\DispatcherAwareInterface; use Joomla\Event\DispatcherInterface; use Joomla\Event\Event; class ContentModel implements DispatcherAwareInterface { const ON_BEFORE_SAVE_EVENT = 'onBeforeSaveEvent'; const ON_AFTER_SAVE_EVENT = 'onAfterSaveEvent'; /** * The underlying dispatcher. * * @var DispatcherInterface */ protected $dispatcher; public function save() { $this->dispatcher->triggerEvent(self::ON_BEFORE_SAVE_EVENT); // Perform the saving. $this->dispatcher->triggerEvent(self::ON_AFTER_SAVE_EVENT); } /** * Set the dispatcher to use. * * @param DispatcherInterface $dispatcher The dispatcher to use. * * @return DispatcherAwareInterface This method is chainable. */ public function setDispatcher(DispatcherInterface $dispatcher) { $this->dispatcher = $dispatcher; } }
不可变事件
不可变事件在实例化后不能被修改
- 其参数不能被修改
- 其传播不能被阻止
当您不希望监听器操作它时(它们只能检查它)很有用。
namespace MyApp; use Joomla\Event\EventImmutable; // Creating an immutable event called onSomething with an argument "foo" with value "bar" $event = new EventImmutable('onSomething', array('foo' => 'bar'));
委派分发器
一个将方法委托给其他Dispatcher的调度器。这是一种实现Dispatcher不可变性的简单方法。
namespace MyApp; use Joomla\Event\DelegatingDispatcher; use Joomla\Event\Dispatcher; $dispatcher = new Dispatcher; // Here you add you listeners and your events.... // Instanciating a delegating dispatcher. $delegatingDispatcher = new DelegatingDispatcher($dispatcher); // Now you inject this dispatcher in your system, and it has only the triggerEvent method.
当你想确保第三方应用程序不会向Dispatcher注册或删除监听器时,这很有用。
通过Composer安装
将"joomla-x/event": "3.0.*@dev"
添加到您的composer.json文件中的require块,然后运行composer install
。
{ "require": { "joomla-x/event": "3.0.*@dev" } }
或者,您可以直接在命令行运行以下命令
composer require joomla-x/event "3.0.*@dev"