Эффективно создавать плагины с помощью шаблона наблюдателя (php) - PullRequest
2 голосов
/ 02 октября 2011

Я внедряю шаблон наблюдателя для всех плагинов для взаимодействия с моим веб-приложением. Теперь я хочу сделать установку плагинов безболезненной (т.е. просто поместить файлы в папку плагинов), как это делают большинство веб-приложений.

Например: Плагин с именем «Awesome Stuff», который выполняет код на основе событий, происходящих в классе Auth и классе Content, будет включать следующие файлы в каталог «/ plugin». AwesomeStuffAuth.php AwesomeStuffContent.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);
        }

   }

}

Это метод __construct (), который я использую с классом Auth, и другие классы будут иметь аналогичные методы.

Это эффективный способ сделать это? Стоит ли мне подключаться к базе данных, чтобы избежать циклического перебора всех объявленных классов? Как насчет простого файла?

Большое спасибо за то, что взглянули на это.

1 Ответ

0 голосов
/ 03 января 2012

Возможным решением будет использование __autoload, чтобы поймать момент, когда плагин запрашивается, и добавить его в список наблюдателей в данный момент, основываясь на соглашениях об именах:

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);
   }
}

Не проверял код, но вы должны понять.Это устраняет необходимость в глобализации и необходимости повторять каждый объявленный класс при каждом создании класса.

...