我正在实现所有插件与我的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,也不需要在每次创建一个类时遍历每个已声明的类。