解析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统计目录下的文件总数及代码行数(去除注释及空行)
Jan 17 PHP
php产生随机数的两种方法实例代码 输出随机IP
Apr 08 PHP
PHP通过session id 实现session共享和登录验证的代码
Jun 03 PHP
PHP 获取文件路径(灵活应用__FILE__)
Feb 15 PHP
解析PHP跨站刷票的实现代码
Jun 18 PHP
PHP 设计模式系列之 specification规格模式
Jan 10 PHP
PHP设计模式之简单投诉页面实例
Feb 24 PHP
制作个性化的WordPress登陆界面的实例教程
May 21 PHP
PHP基于curl后台远程登录正方教务系统的方法
Oct 14 PHP
PHP编程计算两个时间段是否有交集的实现方法(不算边界重叠)
May 30 PHP
laravel5表单唯一验证的实例代码
Sep 30 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
Mar 24 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
为什么《星际争霸》是测试人工智能的理想战场
2019/12/03 星际争霸
php下使用SMTP发邮件的代码
2008/01/10 PHP
php中$this-&amp;gt;含义分析
2009/11/29 PHP
php根据日期判断星座的函数分享
2014/02/13 PHP
php按百分比生成缩略图的代码分享
2014/05/10 PHP
Symfony2 session用法实例分析
2016/02/04 PHP
PHP判断一个数组是另一个数组子集的方法详解
2017/07/31 PHP
JS 弹出层 定位至屏幕居中示例
2014/05/21 Javascript
Jquery注册事件实现方法
2015/05/18 Javascript
js游戏人物上下左右跑步效果代码分享
2015/08/28 Javascript
jQuery插件支持同一页面被多次调用
2016/02/14 Javascript
Vue.js学习笔记之 helloworld
2016/08/14 Javascript
Angular设置title信息解决SEO方面存在问题
2016/08/19 Javascript
你不知道的 javascript【推荐】
2017/01/08 Javascript
jQuery实现弹出窗口弹出div层的实例代码
2017/01/09 Javascript
AngularJS 文件上传控件 ng-file-upload详解
2017/01/13 Javascript
详解小程序循环require之坑
2019/03/08 Javascript
JavaScript碎片—函数闭包(模拟面向对象)
2019/03/13 Javascript
vue移动端城市三级联动组件使用详解
2019/07/26 Javascript
vue中获取滚动table的可视页面宽度调整表头与列对齐(每列宽度不都相同)
2019/08/17 Javascript
JS script脚本中async和defer区别详解
2020/06/24 Javascript
Python 初始化多维数组代码
2008/09/06 Python
Python List cmp()知识点总结
2019/02/18 Python
python之mock模块基本使用方法详解
2019/06/27 Python
Python使用Pandas读写Excel实例解析
2019/11/19 Python
Django用户身份验证完成示例代码
2020/04/03 Python
关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的问题
2020/11/24 Python
Html5原创俄罗斯方块(基于canvas)
2019/01/07 HTML / CSS
纪伊国屋新加坡网上书店:Kinokuniya新加坡
2017/12/29 全球购物
TUMI香港官网:国际领先的行李箱、背囊品牌
2021/03/01 全球购物
葬礼司仪主持词
2014/03/31 职场文书
建设工地安全标语
2014/06/07 职场文书
公司外出活动方案
2014/08/14 职场文书
七夕活动策划方案
2014/08/16 职场文书
2014年村委会工作总结
2014/11/24 职场文书
2014年机关工会工作总结
2014/12/19 职场文书