解析php中反射的应用


Posted in PHP onJune 18, 2013

一  反射的使用:

<?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>

PHP 相关文章推荐
PHP5 安装方法
Jan 15 PHP
PHP 中文处理技巧
Apr 25 PHP
PHP Zip压缩 在线对文件进行压缩的函数
May 26 PHP
php Smarty 字符比较代码
Feb 27 PHP
PHP获取当前日期所在星期(月份)的开始日期与结束日期(实现代码)
Jun 18 PHP
php读取纯真ip数据库使用示例
Jan 26 PHP
phpmyadmin出现Cannot start session without errors问题解决方法
Aug 14 PHP
PHP中创建和验证哈希的简单方法实探
Jul 06 PHP
PHP Header用于页面跳转时的几个注意事项
Oct 21 PHP
php中请求url的五种方法总结
Jul 13 PHP
PHP面向对象程序设计之构造方法和析构方法详解
Jun 13 PHP
PHP 范围解析操作符(::)用法分析【访问静态成员和类常量】
Apr 14 PHP
使用Smarty 获取当前日期时间和格式化日期时间的方法详解
Jun 18 #PHP
解析smarty模板中类似for的功能实现
Jun 18 #PHP
smarty基础之拼接字符串的详解
Jun 18 #PHP
php class中public,private,protected的区别以及实例分析
Jun 18 #PHP
解析thinkphp基本配置 convention.php
Jun 18 #PHP
PHP获取当前日期所在星期(月份)的开始日期与结束日期(实现代码)
Jun 18 #PHP
基于xcache的配置与使用详解
Jun 18 #PHP
You might like
php array_walk() 数组函数
2011/07/12 PHP
php输出xml属性的方法
2015/03/19 PHP
PHP的邮件群发系统phplist配置方法详细总结
2016/03/30 PHP
js left,right,mid函数
2008/06/10 Javascript
基于jquery的获取浏览器窗口大小的代码
2011/03/28 Javascript
JS编程小常识很有用
2012/11/26 Javascript
ScrollDown的基本操作示例
2013/06/09 Javascript
同域jQuery(跨)iframe操作DOM(示例代码)
2013/12/13 Javascript
实现前后端数据交互方法汇总
2015/04/07 Javascript
jquery 将当前时间转换成yyyymmdd格式的实现方法
2016/06/01 Javascript
基于nodejs 的多页面爬虫实例代码
2017/05/31 NodeJs
详解用Node.js写一个简单的命令行工具
2018/03/01 Javascript
cordova+vue+webapp使用html5获取地理位置的方法
2019/07/06 Javascript
如何在面试中手写出javascript节流和防抖函数
2020/10/22 Javascript
使用python统计文件行数示例分享
2014/02/21 Python
Python爬取网易云音乐热门评论
2017/03/31 Python
Django rest framework工具包简单用法示例
2018/07/20 Python
python对列进行平移变换的方法(shift)
2019/01/10 Python
Python写出新冠状病毒确诊人数地图的方法
2020/02/12 Python
FitFlop澳大利亚官网:英国符合人体工学的鞋类品牌
2017/06/05 全球购物
世界上最大的艺术社区:SAA
2020/12/30 全球购物
C/C++ 笔试、面试题目大汇总
2015/11/21 面试题
JVM是一个编译程序还是解释程序
2012/09/11 面试题
工程师求职简历的自我评价分享
2013/10/10 职场文书
期末考试动员演讲稿
2014/01/10 职场文书
安全大检查实施方案
2014/02/22 职场文书
幼儿园中班教师寄语
2014/04/03 职场文书
总经理岗位职责说明书
2014/07/30 职场文书
学生实习证明模板汇总
2014/09/25 职场文书
学习十八届四中全会依法治国心得体会
2014/11/03 职场文书
面试感谢信范文
2015/01/22 职场文书
圣诞晚会主持词开场白
2015/05/28 职场文书
redis实现共同好友的思路详解
2021/05/26 Redis
CKAD认证中部署k8s并配置Calico插件
2022/03/31 Servers
【海涛教你打DOTA】黑鸟第一视角解说
2022/04/01 DOTA
Sql Server 行数据的某列值想作为字段列显示的方法
2022/04/20 SQL Server