webiny/event-manager

Webiny事件管理组件

v1.6.1 2017-09-29 08:12 UTC

README

EventManager 允许您轻松地管理应用程序中的事件。

安装组件

安装组件的最佳方式是使用Composer。

composer require webiny/event-manager

要获取包的额外版本,请访问Packagist页面

用法

访问EventManager可以通过两种方式实现。首选的方式是使用EventManagerTrait,但您也可以直接使用EventManager::getInstance()来访问。以下是一个简单示例,展示了如何订阅名为some.event的事件,并使用YourHandler的实例

class YourClass{
    use EventManagerTrait;
    
    public function index(){
        $this->eventManager()->listen('some.event')->handler(new YourHandler());
    }
}

完成!您已成功订阅了一个事件,当some.event事件被触发时,您的处理器将处理它。

事件处理器

现在让我们看看YourHandler。事件处理器可以是任何类。EventManager将默认调用处理器对象上的handle(Event $event)方法,但是您也可以指定EventManager要调用的方法

class YourHandler{

    public function customHandle(Event $event){
        // Do something with the $event...
    }
    
}

// Using your custom method
$this->eventManager()->listen('some.event')->handler(new YourHandler())->method('customHandle');

除了使用类之外,您还可以使用可调用对象来响应事件

// Using callable as event handler

$handler = function(Event $event){
    // Do something with the $event...
};

$this->eventManager()->listen('some.event')->handler($handler);

触发事件

要触发一个简单的事件,请使用以下代码

$this->eventManager()->fire('some.event');

您也可以在触发事件时传递一些数据,这些数据将被传递给每个事件监听器

$data = [
    'some' => 'data',
    'ip' => '192.168.1.10'
];

$this->eventManager()->fire('some.event', $data);

任何不是Event对象的数据都将转换为通用的Event对象,并且您可以通过使用数组键或作为对象属性来访问您的数据

class YourHandler{

    public function customHandle(Event $event){
        // Access your data 
        echo $event->some; // 'data'
        echo $event['some'] // 'data'
    }
    
}

如果您想使用自定义的Event数据类型,请参阅自定义事件类部分

使用通配符触发事件

您还可以使用通配符一次性触发多个事件。以下代码将触发所有以event.开头的事件,并将$data传递给每个事件

$this->eventManager()->fire('event.*', $data);

执行优先级

EventManager 允许您使用 priority() 方法指定执行优先级。以下是一个示例

// Specify a priority of execution for your event listeners
$this->eventManager()->listen('some.event')->handler(new YourHandler())->method('customHandler')->priority(250);
$this->eventManager()->listen('some.event')->handler(new YourHandler())->method('secondCustomHandler')->priority(400);
$this->eventManager()->listen('some.event')->handler(new YourHandler())->method('thirdCustomHandler');

// Now let's fire an event
$this->eventManager()->fire('some.event');

在触发事件后,事件监听器将按优先级降序排序。优先级越高,监听器执行得越早。在此示例中,执行顺序如下:secondCustomHandlercustomHandlerthirdCustomHandler。默认优先级为 101,因此 thirdCustomHandler 最后执行。

自定义事件类

在触发事件时,您还可以传递自己的事件类,这些类扩展了通用的 Event 类。例如,您想触发名为 cms.page_saved 的事件并传递 Page 对象。当然,您可以简单地将一个数组传递,如 ['page' => $pageObject],但为了示例,让我们假设它比这更复杂

// Create your `PageEvent` class

class PageEvent extends Event{

    private $_page;

    public function __construct(Page $page){
        // Call constructor of parent Event class
        parent::__construct();
        
        // Set your page object
        $this->_page = $page;
    }

    public function getPage(){
        return $this->_page;
    }
    
}

// Fire an event

$pageEvent = new PageEvent($pageObject);

$this->eventManager()->fire('cms.page_saved', $pageEvent);

// In your handler, you can now access page object using $event->getPage()

class YourHandler{

    public function customHandle(PageEvent $event){
        $pageObject = $event->getPage();
    }
    
}

这是一个简单的示例,但它展示了创建自己的 Event 类并添加您所需功能的能力。

事件订阅者

EventManager 的另一个酷功能是能够一次性订阅多个事件。您需要创建一个实现 EventSubscriberInterface 的订阅者类

class PageEventSubscriber implements EventSubscriberInterface {
    use EventManagerTrait;

    /**
     * Handle page creation event
     */
    public function onPageCreated($event)
    {
        //
    }

    /**
     * Handle page update
     */
    public function onPageUpdated($event)
    {
        //
    }

    /**
     * Register the listeners for the subscriber.
     */
    public function subscribe()
    {
        $this->eventManager()->listen('cms.page_created')->handler($this)->method('onPageCreated');
        $this->eventManager()->listen('cms.page_updated')->handler($this)->method('onPageUpdated');
    }

}

// Subscriber to multiple events using your new subscriber class
$this->eventManager()->subscribe($subscriber);

在某些情况下,您可能需要暂时禁用 EventManager。例如,删除与应用程序无关的大量文件(本地缓存文件)不需要触发所有相关事件。在这种情况下,请使用以下方法

// Disabling EventManager
$this->eventManager()->disable();

// Do some work that would fire loads of unnecessary events...

// Enabling EventManager
$this->eventManager()->enable();

资源

要运行单元测试,您需要使用以下命令

$ cd path/to/Webiny/Component/EventManager/
$ composer.phar install
$ phpunit