<?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(); ?>