解析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 相关文章推荐
PHP编程中字符串处理的5个技巧小结
Nov 13 PHP
使用PHP的日期与时间函数技巧
Apr 24 PHP
php生成随机数或者字符串的代码
Sep 05 PHP
php HandlerSocket的使用
May 02 PHP
php计算函数执行时间的方法
Mar 20 PHP
php获得客户端浏览器名称及版本的方法(基于ECShop函数)
Dec 23 PHP
盘点PHP和ASP.NET的10大对比!
Dec 24 PHP
PHP线程的内存回收问题
Jul 08 PHP
php使用curl_init()和curl_multi_init()多线程的速度比较详解
Aug 15 PHP
php 与 nginx 的处理方式及nginx与php-fpm通信的两种方式
Sep 28 PHP
Yii框架核心组件类实例详解
Aug 06 PHP
phpstudy后门rce批量利用脚本的实现
Dec 12 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生成唯一订单号的方法汇总
2015/04/16 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
Thinkphp 框架基础之入口文件功能、定义与用法分析
2020/04/27 PHP
jquery遍历input取得input的name
2009/04/27 Javascript
JQuery中如何传递参数如click(),change()等具体实现
2013/04/28 Javascript
Ajax异步提交表单数据的说明及方法实例
2013/06/22 Javascript
JS增加行复制行删除行的实现代码
2013/11/09 Javascript
jquery动态添加元素事件失效问题解决方法
2014/05/23 Javascript
如何编写高质量JS代码(续)
2015/02/25 Javascript
在jQuery中使用$而避免跟其它库产生冲突的方法
2015/08/13 Javascript
使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
2015/08/21 NodeJs
关于js二维数组和多维数组的定义声明(详解)
2016/10/02 Javascript
JS实现的文字间歇循环滚动效果完整示例
2018/02/13 Javascript
Vue组件库发布到npm详解
2018/02/17 Javascript
Angular @HostBinding()和@HostListener()用法
2018/03/05 Javascript
vue 的keep-alive缓存功能的实现
2018/03/22 Javascript
全面解析vue router 基本使用(动态路由,嵌套路由)
2018/09/02 Javascript
vue + axios get下载文件功能
2019/09/25 Javascript
jquery实现手风琴案例
2020/05/04 jQuery
[14:56]教你分分钟做大人:巫医
2014/10/30 DOTA
[46:43]DOTA2上海特级锦标赛D组小组赛#1 EG VS COL第三局
2016/02/28 DOTA
Python编程修改MP3文件名称的方法
2017/04/19 Python
python绘制直线的方法
2018/06/30 Python
解决Mac下首次安装pycharm无project interpreter的问题
2018/10/29 Python
用python脚本24小时刷浏览器的访问量方法
2018/12/07 Python
使用pandas读取文件的实现
2019/07/31 Python
scrapy redis配置文件setting参数详解
2020/11/18 Python
美国棒球装备和用品商店:Baseball Savings
2018/06/09 全球购物
贝尔帐篷精品店:Bell Tent Boutique
2019/06/12 全球购物
班级读书活动总结
2014/06/30 职场文书
中学生旷课检讨书2篇
2014/10/09 职场文书
营销计划书
2015/01/17 职场文书
毕业典礼主持词
2015/06/29 职场文书
2016教师节感恩话语
2015/12/09 职场文书
2016年“12.3”国际残疾人日活动总结
2016/04/01 职场文书
CSS完成视差滚动效果
2021/04/27 HTML / CSS