解析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 相关文章推荐
DISCUZ 分页代码
Jan 02 PHP
PHP+MySQL 制作简单的留言本
Nov 02 PHP
PHP 数据结构 算法描述 冒泡排序 bubble sort
Jul 10 PHP
PHP explode()函数用法、切分字符串
Oct 03 PHP
php解析json数据实例
Aug 19 PHP
初识php MVC
Sep 10 PHP
PHP中使用php://input处理相同name值的表单数据
Feb 03 PHP
php生成RSS订阅的方法
Feb 13 PHP
php实现网站顶踩功能的完整前端代码
Jul 19 PHP
php 二维数组快速排序算法的实现代码
Oct 17 PHP
Laravel开启跨域请求的方法
Oct 13 PHP
如何在Laravel之外使用illuminate组件详解
Sep 20 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的库,结果发现很多东西
2006/12/31 PHP
php生成的html meta和link标记在body标签里 顶部有个空行
2010/05/18 PHP
php跨域cookie共享使用方法
2014/02/20 PHP
PHP图片处理之图片旋转和图片翻转实例
2014/11/19 PHP
Laravel如何使用Redis共享Session
2018/02/23 PHP
在laravel中实现事务回滚的方法
2019/10/10 PHP
JS关键字变色实现思路及代码
2013/02/21 Javascript
jquery 绑定回车动作扑捉回车键触发的事件
2014/03/26 Javascript
超级给力的JavaScript的React框架入门教程
2015/07/02 Javascript
js初始化验证实例详解
2016/11/26 Javascript
微信小程序新增的拖动组件movable-view使用教程
2017/05/20 Javascript
vue-quill-editor插入图片路径太长问题解决方法
2021/01/08 Vue.js
nodejs中使用worker_threads来创建新的线程的方法
2021/01/22 NodeJs
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
[04:46]2018年度玩家喜爱的电竞媒体-完美盛典
2018/12/16 DOTA
python中requests模块的使用方法
2015/04/08 Python
Python实现自动上京东抢手机
2018/02/06 Python
使用memory_profiler监测python代码运行时内存消耗方法
2018/12/03 Python
python使用正则筛选信用卡
2019/01/27 Python
Python 日期时间datetime 加一天,减一天,加减一小时一分钟,加减一年
2020/04/16 Python
详解Python IO编程
2020/07/24 Python
python如何支持并发方法详解
2020/07/25 Python
美国专营婴幼儿用品的购物网站:buybuy BABY
2017/01/01 全球购物
下列程序在32位linux或unix中的结果是什么
2014/03/25 面试题
致长跑运动员加油稿
2014/02/20 职场文书
校园歌咏比赛主持词
2014/03/18 职场文书
2014年设备管理工作总结
2014/11/26 职场文书
2014年小学语文工作总结
2014/12/20 职场文书
全国爱牙日活动总结
2015/02/05 职场文书
端午节寄语2015
2015/03/23 职场文书
证券公司客户经理岗位职责
2015/04/09 职场文书
2015社区六五普法工作总结
2015/04/21 职场文书
医院见习总结
2015/06/24 职场文书
pytorch 运行一段时间后出现GPU OOM的问题
2021/06/02 Python
详解MySQL多版本并发控制机制(MVCC)源码
2021/06/23 MySQL
使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐)
2022/01/18 PostgreSQL