解析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 相关文章推荐
用缓存实现静态页面的测试
Dec 06 PHP
php 进度条实现代码
Mar 10 PHP
PHP 5.3新特性命名空间规则解析及高级功能
Mar 11 PHP
PHP读取数据库并按照中文名称进行排序实现代码
Jan 29 PHP
Yii把CGridView文本框换成下拉框的方法
Dec 03 PHP
php隐藏实际地址的文件下载方法
Apr 18 PHP
php实现编辑和保存文件的方法
Jul 20 PHP
在Mac OS上自行编译安装Apache服务器和PHP解释器
Dec 24 PHP
Zend Framework动作助手Redirector用法实例详解
Mar 05 PHP
24条货真价实的PHP代码优化技巧
Jul 28 PHP
PHP7 错误处理机制修改
Mar 09 PHP
PHP中国际化的字符串排序和比较对象详解
Aug 23 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
第一个无线电台是由谁发明的
2021/03/01 无线电
新版mysql+apache+php Linux安装指南
2006/10/09 PHP
PHP函数实现从一个文本字符串中提取关键字的方法
2015/07/01 PHP
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
跨浏览器开发经验总结(四) 怎么写入剪贴板
2010/05/13 Javascript
js读取本地excel文档数据的代码
2010/11/11 Javascript
更优雅的事件触发兼容
2011/10/24 Javascript
微信WeixinJSBridge API使用实例
2015/05/25 Javascript
谈谈我对JavaScript DOM事件的理解
2015/12/18 Javascript
bootstrap多种样式进度条展示
2016/12/20 Javascript
jQuery仿IOS弹出框插件
2017/02/18 Javascript
jquery.form.js异步提交表单详解
2017/04/25 jQuery
angularJs中datatable实现代码
2017/06/03 Javascript
javaScript动态添加Li元素的实例
2018/02/24 Javascript
关于vue中 $emit的用法详解
2018/04/12 Javascript
微信运维交互机器人的示例代码
2018/11/12 Javascript
JQuery基于FormData异步提交数据文件
2020/09/01 jQuery
python在linux中输出带颜色的文字的方法
2014/06/19 Python
Python中使用md5sum检查目录中相同文件代码分享
2015/02/02 Python
pytorch 把MNIST数据集转换成图片和txt的方法
2018/05/20 Python
numpy和pandas中数组的合并、拉直和重塑实例
2019/06/28 Python
scrapy数据存储在mysql数据库的两种方式(同步和异步)
2020/02/18 Python
python的列表List求均值和中位数实例
2020/03/03 Python
python 基于wx实现音乐播放
2020/11/24 Python
美国一家著名的儿童鞋制造商:Stride Rite
2017/01/02 全球购物
英国电视和家用电器购物网站:rlrdistribution.co.uk
2018/11/20 全球购物
日本著名的服饰鞋帽综合类购物网站:MAGASEEK
2019/01/09 全球购物
文秘专业应届生求职信范文
2013/11/14 职场文书
《赵州桥》教学反思
2014/02/17 职场文书
《美丽的黄昏》教学反思
2014/02/28 职场文书
公司演讲稿开场白
2014/08/25 职场文书
副总经理岗位职责范本
2014/09/30 职场文书
应聘教师求职信范文
2015/03/20 职场文书
浅谈Python协程asyncio
2021/06/20 Python
redis缓存存储Session原理机制
2021/11/20 Redis
Win11怎么解除儿童账号限制?Win11解除微软儿童账号限制方法
2022/07/07 数码科技