您的位置:首页 > 其它

利用反射api来加载模块

2011-05-16 21:55 357 查看
<?php
/*
* Created on 2011-5-16
*
* To change the template for this generated file go to
* Window - Preferences - PHPeclipse - PHP - Code Templates
*/
//假设我们要创建要给类来动态调用Module对象,即该类可以自由加载第三
//方插件并集成进已有的系统,而不需要把第三方的代码硬编码进原有的代
//码。要达到这个目的,可以在Module接口或抽象类中定义一个execute()
//方法,强制要求所有的子类都必须实现该方法。可以允许用户在外部XML配
//置文件中列出所有Module类。系统可以使用XML提供的信息来加载一定数目
//的Module对象,然后调用其中的execute().
//
//    然而,如果每个Module需要不同的信息来完成任务,应该怎么做呢?
//    这这种情况下,XML文件可以为每个Module提供属性键和值,Module
//    的创建者可以为每个属性名提供setter方法。代码要确保根据某个属
//    性名调用正确的setter方法。

class Person {
public    $name;

function __construct($name)
{
$this->name = $name;
}
}

interface Module{

function execute();

}

class FtpModule implements Module{

function setHost($host){

print "FtpModule::setHost():$host\n<br>";

}

function setUser($user)
{

print "FtpModule::setUser():$user\n<br>";

}

function execute()
{

}

}

class PersonModule  implements Module{

function setPerson(Person $person)
{

print "PersonModule::setPerson():{$person->name}\n<br>";

}

function execute()
{

}

}

class ModuleRunner {

private $modules = array();

private $configData = array(

"PersonModule"=> array('person'=>'bob'),

"FtpModule"=> array('host'=>'example.com','user'=>'anon' ));

public function init()
{
$interface = new ReflectionClass('Module');

foreach($this->configData as $modulename =>$params)
{
$module_class = new ReflectionClass($modulename);

if(!$module_class->isSubclassOf($interface)){

throw new Exception("unkown module type:$modulename");
}

$module = $module_class->newInstance();

foreach($module_class->getMethods()  as $method )
{

$this->handleMethod($module,$method,$params);

}

array_push($this->modules,$module);

}

}

public function handleMethod(Module $module,ReflectionMethod $method,$params)
{
$name = $method->getName();

$args  = $method->getParameters();

if(count($args)!=1 || substr($name,0,3)!="set") {
return false;
}

$property= strtolower(substr($name,3));

if(!isset($params[$property]) ){ return false;}

$arg_class = $args[0]->getClass();

if(emptyempty($arg_class) ){

$method->invoke($module,$params[$property]);

}else{

$method->invoke($module,$arg_class->newInstance($params[$property]));

}

}

}

$test = new ModuleRunner();

$test->init();

?>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: