php事件系统实现

时间:2013-12-01 20:01:38

标签: php events

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

然而,鉴于php的性质没有任何架构,我似乎无法找到正确的实现。

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

你怎么能绕过这种情况? 我错误地接近了吗?

非常感谢任何想法

2 个答案:

答案 0 :(得分:5)

在触发事件之前必须有一个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方法。如果你愿意,你也可以有一个抽象的事件类。

答案 1 :(得分:0)

我为自己做了一个非常简单的PHP Event Dispatcher / Event Hander,它是可测试的并且已在我的网站上使用过。

如果您需要,可以看看。