<?php
class Person{
public $name;
function __construct($name){
$this->name = $name;
}
}
interface Module{
function execute();
}
class FtpModule implements Module{
private $host;
private $user;
function setHost($host){
$this->host = $host;
echo "FtpModule::setHost() : {$this->host} <br/>";
}
function setUser($user){
$this->user = $user;
echo "FtpModule::setUser() : {$this->user} <br/>";
}
function execute(){
//执行一些操作
echo "Host: {$this->host} & User: {$this->user} <br/>";
}
}
class PersonModule implements Module{
private $name;
function setPerson( Person $person ){
$this->name = $person->name;
echo "PersonModule::setPerson() : {$person->name} <br/>";
}
function execute(){
//执行一些操作
echo "Name: {$this->name}<br />";
}
}
class ModuleRunner{
private $configData = array(
"PersonModule" => array('person'=>'leokim'),
"FtpModule" => array('host'=>'www.leokim.cn','user'=>'leokim')
);
private $modules = array();
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("unknow module type:$modulename");
}
$module = $module_class->newInstance();
foreach($module_class->getMethods() as $method){
//module,module内的方法,方法的参数
$this->handleMethod($module, $method, $params);
}
array_push($this->modules, $module);
}
}
//handleMethod()检验并调用Module对象的setter方法
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;
}
print_r($args[0]);
echo ' | ';
//ReflectionMethod::invoke()。它以一个对象和任意数目的方法作为参数
//可以通过两种途径调用invoke()方法:
//1.如果setter方法不需要对象参数,可以用用户提供的属性字符串来调用ReflectionMethod::invoke()。
//2.如果方法需要对象作为参数,可以使用属性字符串来实例化正确类型的对象,然后传递给setter。
//这个例子里 Person是有Class的 所以在else里执行,Ftp并没有Class所以在if里执行
$arg_class = $args[0]->getClass();
if(empty($arg_class)){
$method->invoke($module, $params[$property]);
}else{
$method->invoke($module, $arg_class->newInstance($params[$property]));
}
//执行固有的function execure()
$module->execute();
}
}
//在ModuleRunner::init()方法运行时,ModuleRunner对象存储着许多Module对象,而所有Module对象都包含着数据。
//ModuleRunner类现在可以用一个类方法来循环遍历没个Module对象,并逐一调用各Module对象中的excute()方法
$test = new ModuleRunner();
$test->init();
?>