phossa2/event

此包已废弃,不再维护。未建议替代包。

PHP的PSR-14事件管理器实现库

2.1.6 2016-08-26 01:39 UTC

This package is not auto-updated.

Last update: 2020-01-24 16:22:48 UTC


README

请使用phoole/event库替代

Build Status Code Quality Code Climate PHP 7 ready HHVM Latest Stable Version License

phossa2/event是PHP的PSR-14事件管理器库。

它需要PHP 5.4,支持PHP 7.0+和HHVM。它符合PSR-1PSR-2PSR-4和即将推出的PSR-14

安装

通过composer工具安装。

composer require "phossa2/event=2.1.*"

或者将以下行添加到您的composer.json文件中

{
    "require": {
       "phossa2/event": "^2.1.0"
    }
}

特性

用法

  • 快速入门

    use Phossa2\Event\EventDispatcher;
    
    // event dispatcher
    $events = new EventDispatcher();
    
    // bind event with a callback
    $events->attach('login.success', function($evt) {
        echo "logged in as ". $evt->getParam('username');
    });
    
    // bind event with a callable
    $events->attach('login.attempt', [$logger, 'logEvent']);
    
    // unbind an event
    $events->clearListeners('login.attempt');
    
    // fire the trigger
    $events->trigger('login.success');
  • 事件名称globbing

    事件名称globbing意味着当触发事件'login.success'时,绑定'login.*'的可调用项也将被触发。

    // bind 'login.*' with callables
    $events->attach('login.*', function($evt) {
        echo $evt->getName();
    });
    
    // trigger 'login.atttempt' will also trigger callables of 'login.*'
    $events->trigger('login.attempt');

    globbing规则类似于PHP函数glob(),其中

    • *在字符串中表示除了点以外的任何字符。

    • 如果*在末尾,将匹配包括点在内的任何字符。例如,login.*将匹配'login.attempt.before'。

    • .表示点。

    • 单字符字符串*表示匹配任何字符串(包括点)。

    注意:名称globbing只在触发事件时发生。绑定或解绑事件仅影响确切的事件名称。

    // unbind the exact 'login.*'
    $events->clearListeners('login.*');
  • 共享事件管理器支持

    EventDispatcher实现了Phossa2\Shared\Shareable\ShareableInterface

    ShareableInterface是单例模式的扩展版本。它不仅支持一个共享实例,实现ShareableInterface的类还可以为不同的范围有不同的共享实例。

    // global event manager, global scope is ''
    $globalEvents = EventDispatcher::getShareable();
    
    // shared event manager in scope 'MVC'
    $mvcEvents = EventDispatcher::getShareable('MVC');
    
    // an event manager instance, which has scope 'MVC'
    $events = new EventDispatcher('MVC');
    
    // in scope MVC ?
    var_dump($events->hasScope('MVC')); // true
    
    // in global scope ?
    var_dump($events->hasScope()); // true

    如果事件管理器实例具有相同的范围,绑定到共享管理器的可调用项也将被触发。

    // shared event manager in scope 'MVC'
    $mvcEvents = EventDispatcher::getShareable('MVC');
    
    // bind with pirority 100 (highest priority)
    $mvcEvents->attach('*', function($evt) {
        echo "mvc";
    }, 100);
    
    // create a new instance within the MVC scope
    $events = new EventDispatcher('MVC');
    
    // bind with default priority 0
    $events->attach('test', function($evt) {
        echo "test";
    });
    
    // will also trigger matched events in $mvcEvents
    $events->trigger("test");

    事件管理器实例可以具有多个范围,这些范围可以在实例化时指定或使用addScope()指定。

    // create an event manager with 2 scopes
    $events = new EventDispatcher(['MVC', 'AnotherScope']);
    
    // add another scope
    $events->addScope('thirdScope');

    提供了一些辅助方法,用于使用共享管理器开启/关闭/触发事件。

    // bind a callable to global event manager
    EventDispatcher::onGlobalEvent('login.success', function() {});
    
    // use interface name as a scope
    EventDispatcher::onEvent(
        'Psr\\Log\\LoggerInterface', // scope
        'log.error', // event name
        function () {}
    );
    
    // unbind all callables of event 'log.error' in a scope
    EventDispatcher::offEvent(
        'Psr\\Log\\LoggerInterface',
        'log.error'
    );
    
    // unbind *ALL* events in global scope
    EventDispatcher::offGlobalEvent();
  • 附加监听器

    Listener实现了ListenerInterface。或者简而言之,提供了一种方法eventsListening()

    use Phossa2\Event\Interfaces\ListenerInterface;
    
    class myListener implements ListenerInterface
    {
        public function eventsListening()
        {
            return [
                // one method of $this
                eventName1 => 'method1',
    
                // 2 methods
                eventName2 => ['callable1', 'method2'],
    
                // priority 20 and in a 'mvcScope' scope
                eventName2 => ['method2', 20, 'mvcScope'], // with priority 20
    
                eventName3 => [
                    ['method3', 50],
                    ['method4', 70, 'anotherScope']
                ]
            ];
        }
    }

    EventDispatcher::attachListener() 可以用于绑定在 eventsListening() 中定义的事件,而不是使用 EventDispatcher::attach() 手动绑定每个事件。

    $events = new EventDispatcher();
    
    $listener = new \myListener();
    
    // bind all events defined in $listener->eventsListening()
    $events->attachListener($listener);
    
    // will call $listener->method1()
    $events->trigger('eventName1');
  • 静态使用事件管理器

    StaticEventDispatcher 是一个用于 EventDispatcher 从属对象的静态包装器。

    StaticEventDispatcher::attach('*', function($evt) {
        echo 'event ' . $evt->getName();
    });
    
    // will print 'event test'
    StaticEventDispatcher::trigger('test');

    StaticEventDispatcher 与全局事件管理器不同。 StaticEventDispatcher 具有一个默认从属对象,这是一个在作用域 '__STATIC__' 中的共享事件管理器。而全局事件管理器是全局作用域 '' 中的共享事件管理器。

    用户可以设置另一个事件管理器以替换默认从属对象。

    StaticEventDispatcher::setEventManager(new EventDispatcher());
  • EventCapableAbstract

    EventCapableAbstract 实现了 ListenerInterfaceEventCapableInterface。当调用 triggerEvent() 时,它会执行以下操作:

    • 获取事件管理器。如果没有设置,则创建一个默认事件管理器,其作用域为当前类名。

    • 如果尚未绑定,则附加 eventsListening() 中定义的事件。

    • 触发事件,并由事件管理器和所有作用域的共享管理器处理。

    class LoginController extends EventCapableAbstract
    {
        public function login() {
    
            // failed
            if (!$this->trigger('login.pre')) {
                return;
            }
    
            // ...
        }
    
        public function beforeLogin() {
            // ...
        }
    
        public function eventsListening()
        {
            return [
                'login.pre' => 'beforeLogin'
            ];
        }
    }
  • EventableExtensionAbstractEventableExtensionCapableAbstract

    EventableExtensionCapableAbstract 是支持事件和扩展的基类。

    详细用法可以在 phossa2/cache 中找到,Phossa2\Cache\CachePool 扩展了 EventableExtensionCapableAbstract,而 Phossa2\Cache\Extension\ByPass 扩展了 EventableExtensionAbstract

    或查看 phossa2/route

  • 类或接口级别的事件支持

    类或接口名称可以用作 scope。当将事件绑定到这类作用域时,任何由子类触发的事件也会在父类/接口级别共享事件管理器中搜索可调用的对象。

    // define event '*' for interface 'MyInterface'
    EventDispatcher::onEvent(
        'MyInterface', '*', function() { echo "MyInterface"; }, 60
    );

    扩展 EventCapableAbstract

    class MyClass extends EventCapableAbstract implements MyInterface
    {
        public function myMethod()
        {
            echo "myMethod";
        }
    
        public function eventsListening()/*# : array */
        {
            return [
                // priority 20
                'afterTest' => ['myMethod', 20]
            ];
        }
    }
    
    $obj = new MyClass();
    
    // will trigger callable 'myMethod' and handlers for 'MyInterface'
    $obj->trigger('afterTest');
  • 限制调用次数的调用对象

    // bind a callable for executing only once
    $events->one('user.login', function(Event $evt) {
        // ...
    });
    
    // 3 times
    $events->many(3, 'user.tag', function(Event $evt) {
        // ...
    });

变更日志

请参阅 CHANGELOG 获取更多信息。

测试

$ composer test

贡献

请参阅 CONTRIBUTE 获取更多信息。

依赖

  • PHP >= 5.4.0

  • phossa2/shared >= 2.0.21

许可

MIT 许可