php事件系统实现


php event system implementation

我想在我的自定义MVC框架中实现一个事件系统,以允许解耦需要相互交互的类。基本上,任何类触发事件的能力,以及任何其他侦听该事件的类能够挂接该事件的能力

然而,考虑到php的sharenothing架构的性质,我似乎找不到正确的实现。

例如,假设我有一个用户模型,每次更新它时,它都会触发一个userUpdate事件。现在,这个事件对类A很有用(例如),因为它需要在更新用户时应用自己的逻辑。但是,在更新用户时不会加载类A,因此它无法绑定到user对象触发的任何事件。

你怎么能避开这种情况?我是不是搞错了?

任何想法都将不胜感激

在触发事件之前必须有一个类A的实例,因为您必须注册该事件。如果您注册了一个静态方法,则会出现一个例外。

假设您有一个User类,它应该触发一个事件。首先,您需要一个(抽象的)事件调度程序类。这种事件系统的工作方式类似ActionScript3:

abstract class Dispatcher
{
    protected $_listeners = array();
    public function addEventListener($type, callable $listener)
    {
        // fill $_listeners array
        $this->_listeners[$type][] = $listener;
    }
    public function dispatchEvent(Event $event)
    {
        // call all listeners and send the event to the callable's
        if ($this->hasEventListener($event->getType())) {
            $listeners = $this->_listeners[$event->getType()];
            foreach ($listeners as $callable) {
                call_user_func($callable, $event);
            }
        }
    }
    public function hasEventListener($type)
    {
        return (isset($this->_listeners[$type]));
    }
}

您的User类现在可以扩展Dispatcher:

class User extends Dispatcher
{
    function update()
    {
        // do your update logic
        // trigger the event
        $this->dispatchEvent(new Event('User_update'));
    }
}

如何注册该活动?假设您有方法为update的类A。

// non static method
$classA = new A();
$user = new User();
$user->addEventListener('User_update', array($classA, 'update'));
// the method update is static
$user = new User();
$user->addEventListener('User_update', array('A', 'update'));

如果您有适当的自动加载,则可以调用静态方法。在这两种情况下,Event都将作为参数发送给update方法。如果你喜欢的话,你也可以有一个抽象的Event类。

我为自己制作了一个非常简单的PHP事件调度程序/事件处理程序,它是可测试的,并已在我的网站上使用。

如果你需要,你可以看看。