PHP 事件侦听器最佳实践实现

2022-08-30 10:31:48

我正在尝试在PHP中创建一个类似CMS的系统。使其尽可能模块化和可扩展。

有人可以为我提供在PHP中创建事件侦听器系统的最佳实践方案(例如Drupal系统的一个非常简化的版本),创建钩子并在一个简短的示例中实现它们也会很好。


答案 1

好吧,从实现的角度来看,实际上有三种不同的方法来做到这一点(请注意,这些是OO设计模式,但如果你愿意,你可以在功能上或程序上实现它们)。

1. 观察者模式

您可以实现观察者模式。基本上,每个可以引发事件的事情都会成为一个主题。然后,您要侦听的类/代码将绑定到它想要专门侦听的内容。假设您有一个名为 .如果你想听它,你可以打电话给.然后,每当控制器想说些什么时,它就会将事件发送给所有观察者。Foo$fooController->attach($observer);

这非常适合通知系统(扩展类正在执行的操作)。它不太适合实时修改代码的行为。

2.装饰器模式 您还可以实现装饰器模式。基本上,您将要修改的对象“包装”在一个新对象中,该对象执行要更改的内容。这非常适合修改和扩展行为(因为您可以有选择地覆盖包装类中的功能)。

如果您定义了接口并期望对象符合它们,则此方法非常有效。如果您没有界面(或者没有正确使用它们),则装饰器模式可以为您完成的大部分操作都将丢失。

另请注意,这实际上不是一种执行事件的方式,而是一种修改对象行为的方法。

3. 中介模式

您也可以使用调解员。基本上,你会有一个全球调解员来跟踪你的听众。当您想要触发事件时,请将该事件发送给中介程序。然后,中介程序可以跟踪哪些侦听对象希望接收该事件,并正确传递消息。

这具有中心的优势。这意味着多个发送者可以发送相同的事件,对于侦听器来说,发送者并没有区别......

我在一篇博客文章中扩展了这个主题。


答案 2
/*
 Example 1: 
 event::bind('blog.post.create', function($args = array())
 {
    mail('myself@me.com', 'Blog Post Published', $args['name'] . ' has been published');
});

 Example 2: 
 event::trigger('blog.post.create', $postInfo);
*/

class event
{
    public static $events = array();

    public static function trigger($event, $args = array())
    {
        if(isset(self::$events[$event]))
        {
            foreach(self::$events[$event] as $func)
            {
                call_user_func($func, $args);
            }
        }

    }

    public static function bind($event, Closure $func)
    {
        self::$events[$event][] = $func;
    }
}

推荐