使用观察者模式(php)有效地实例化插件


Instantiate plugins efficiently with observer pattern (php)

我正在实现所有插件与我的web应用程序交互的观察者模式。现在,我想使安装插件无痛(即只是把文件放入插件文件夹)像大多数web应用程序。

例如

:一个名为"Awesome Stuff"的插件,根据Auth类和Content类中发生的事件执行代码,将包括"/plugin"目录下的以下文件。AwesomeStuffAuth.phpAwesomeStuffContent.php

我有一个解决方案,工作,但我担心它不是有效的,因为它必须循环遍历所有声明的类之前,它实际上找到它正在寻找的。

    function __construct() {
   //Get files in plugin directory that work on Auth
   foreach (glob("plugins/*AuthPlugin.php") as $filename) {
    //Include'em
    include_once($filename);

   }
   //Get all declared classes
   foreach (get_declared_classes() as $class){
        if (substr($class,-10)=='AuthPlugin'){
            $obj = new $class;
            $this->addObserver($obj);
        }
   }

}

这是我对Auth类使用的__construct()方法,其他类也会有类似的方法。

这是一种有效的方法吗?是否值得我连接到数据库,以避免循环通过所有声明的类?平面文件呢?

谢谢你看这个

一个可能的解决方案是使用__autolload来捕捉请求插件的时刻,并根据命名约定将其添加到当前的观察者列表中:

function __autoload($class) {
     include_once 'plugins/' . $class . '.php';
     $observable = substr($class,-16);  # E.g. 'Auth'
     $observable::addObserverClass($class); 
}

然后在Auth类中:

class Observable {
   static $observer_classes = array();
   static function addObserverClass($class) {
      self::$observer_classes[] = $class;
   }
   static function addObservers($self) {
      foreach(self::$observer_classes as $class) {
         $self->addObserver($class);
      }
   }
   function addObserver($class) {
      # Add the Observer.
   }
}
class Auth extends Observable {
   function __construct() {
      self::addObservers($self);
   }
}

还没有测试代码,但你应该知道。它既不需要glob,也不需要在每次创建一个类时遍历每个已声明的类。