解析php中反射的应用

一  反射的使用:

  

复制代码 代码如下:

  <?php

  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";

  }

  function setUser($user){

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

  }

  function execute(){

  //something

  }

  }

  class PersonModule implements Module{

  function setPerson(Person $person){

  print "PersonModule::setPerson:{$person->name}\n";

  }

  function execute(){

  //something

  }

  }

  class ModuleRunner{

  private $configData

  =array(

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

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

  );

  private $modules=array();

  function init(){

  $interface=new ReflectionClass('Module');

  foreach($this->configData as $modulename=>$params){

  $module_class=new ReflectionClass($modulename);//根据配置configData的名称,实例化ReflectionClass

  if(!$module_class->isSubclassOf($interface)){//检查反射得到了类是否是$interface的子类

  throw new Exception("unknown module type:$modulename");//不是Module子类则抛出异常

  }

  $module=$module_class->newInstance();//实例化一个FtpModule或者PersonModule对象

  foreach($module_class->getMethods() as $method){//获得类中的方法

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

  }

  array_push($this->modules,$module);//将实例化的module对象放入$modules数组中

  }

  }

  function handleMethod(Module $module,ReflectionMethod $method,$params){

  $name=$method->getName();//获得方法名称

  $args=$method->getParameters();//获得方法中的参数

  if(count($args)!=1||substr($name,0,3)!="set"){//检查方法必须是以set开头,且只有一个参数

  return false;

  }

  $property=strtolower(substr($name,3));//讲方法名去掉set三个字母,作为参数

  if(!isset($params[$property])){//如果$params数组不包含某个属性,就返回false

  return false;

  }

  $arg_class=@$args[0]->getClass;//检查setter方法的第一个参数(且唯一)的数据类型

  if(empty($arg_class)){

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

  }else{

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

  }

  }

  }

  $test=new ModuleRunner();

  $test->init();

  ?>

  二  通过反射获得类中信息:

  

复制代码 代码如下:

  <PRE class=php name="code"><?php

  class ReflectionUtil{

  static function getClassSource(ReflectionClass $class){

  $path=$class->getFileName();

  $lines=@file($path);

  $from=$class->getStartLine();

  $to=$class->getEndLine();

  $len=$to-$from+1;

  return implode(array_slice($lines,$from-1,$len));

  }

  }

  $classname="Person";

  $path="../practice/{$classname}.php";

  if(!file_exists($path)){

  throw new Exception("No such file as {$path}");

  }

  require_once($path);

  if(!class_exists($classname)){

  throw new Exception("No such class as {$classname}");

  }

  print ReflectionUtil::getClassSource(new ReflectionClass('Person'));

  ?>

  </PRE><BR>

  <PRE></PRE>

  结果是:class Person{ public $age; public $name; function getName(){return "zjx";} function getAge(){return 12;} function __toString(){ $rs=$this->getName(); $rs.="(age".$this->getAge().")"; return $rs; } }

  <PRE></PRE>

  <PRE></PRE>

  <PRE></PRE>

  <PRE></PRE>