讲到这个实例,首先介绍下本人,我是一个php程序猿。从事drupal开发2年多。能够说从实习開始就接触这个,至今没有换过。drupal给我的感觉是俩字“强大”,今天写一个views的字段。然后须要继承views的views_handler_field类,还要自己实现里面的一些方法,走一些自己的配置设置,查看这个类的时候,发现实在是太多信息了,而且做了好些继承,于是我就想要是能实现一个功能,传入一个类名,然后就能返回类的全部信息(包含,属性,方法,继承,接口,而且这些类所放置的文件位置,以及在该文件的多少行)在使用drupal中的dpm函数一打印(层级查询。这是一个插件名字叫【krumo】),我赛这想法太好了啊。

。。

。。越想越有兴趣实现他了,

接下来我就想这该怎么实现呢。后来突然想到了。前些日子看的php模式与面向对象一书中有一章节叫反射api的,对了就是它。接下来開始coding............................

由于好长时间没有写类了,由于drupal还是一个函数式编程的概念,所以这个类写的不是太好,好希望大家多多不吝赐教。一起成长,以下附上代码。

<?

php
/**
* use
* $pros = new RefTools('calssname', true, false);
* dpm($pros->Cinfo()); print_r($pros->Cinfo());
*/
class RefTools {
public $p_num;
public $classname;
public $isgetpar; /**
* [constructor 构造方法]
* @param [type] $classname [类名]
* @return [type] [null]
*/
public function __construct($classname, $isgetpar=true){
$this->classname = $classname;
$this->p_num = 0;
$this->isgetpar = $isgetpar;
} /**
* [cInfo description]
* @return [type] [description]
*/
public function cInfo() {
return $this->getClassMethod($this->classname);
}
/**
* [getReflectionObj 获取反射对象]
* @param [type] $classname [类名]
* @return [type] [对象]
*/
public function getReflectionObj($classname){
//这里假设这样传參$this->classname,会导致运行时间太长而栈溢出,我的測试环境开启了xdebug,有xdebug.max_nesting_level=150
//限制,可是通过传递參数就不会有此原因,知道的人一起交流交流
return new ReflectionClass($classname);
} /**
* [getClassMethod 获取类方法]
* @param [type] $classname [类名]
* @param boolean $isgetpar [是否继续查询父类]
* @return [type] [数组]
*/
public function getClassMethod($classname){
$arr = array();
//获取反射对象
$pre = $this->getReflectionObj($classname);
//获取反射对象的方法
$methods = $pre->getMethods();
$arr['tostring'] = $pre->__toString();
$arr['classinfo'] = $this->getClassInfo($pre);
$arr['Properties'] = $this->getPropertiesData($pre->getProperties());
foreach ($methods as $key => $method) {
$arr['method'][$method->getName()]['info'] = $this->getMethodData($method);
$arr['method'][$method->getName()]['body'] = $this->getMethodSource($method);
} //是否获取父类
if( $this->isgetpar ){
$parclass = $pre->getParentClass();
if(is_object($parclass)){
$this->p_num++;
$arr['parents'][$parclass->name] = $this->getClassMethod($parclass->name,true,false);
}
}
$arr['parent_num'] = $this->p_num;
return $arr;
} /**
* [getClassInfo 获取类信息]
* @param [type] $pre [反射类对象]
* @return [type] [description]
*/
public function getClassInfo($pre){
$arr = array();
$arr['path'] = $pre->getFileName();
$arr['line'] = 'start:'.$pre->getStartLine().'****end:'.$pre->getEndLine();
$arr['interface'] = $pre->getInterfaceNames();
return $arr;
} /**
* [getPropertiesDataa 获取属性信息]
* @param [type] $properties [arr]
* @return [type] [string]
*/
public function getPropertiesData( $properties ){
$arr = array();
foreach ($properties as $key => $pp) {
$pname = $pp->getName();
$arr[$pname] = '****来自于 '.$pp->class.' 类****';
}
return $arr;
} /**
* [getMethodData 获取类方法信息]
* @param ReflectionMethod $method [方法对象]
* @return [type] [string]
*/
public function getMethodData( ReflectionMethod $method ){
$details = '';
$name = $method->getName();
if ( $method->isUserDefined() ) {
$details .= "****** 【 $name 】 ******* is user defined\n";
} if ( $method->isInternal() ) {
$details .= "****** 【 $name 】 ******* is built-in\n";
} if ( $method->isAbstract() ) {
$details .= "****** 【 $name 】 ******* is abstract\n";
} if ( $method->isPublic() ) {
$details .= "****** 【 $name 】 ******* is public\n";
} if ( $method->isProtected() ) {
$details .= "****** 【 $name 】 ******* is protected\n";
} if ( $method->isPrivate() ) {
$details .= "****** 【 $name 】 ******* is private\n";
} if ( $method->isStatic() ) {
$details .= "****** 【 $name 】 ******* is static\n";
} if ( $method->isFinal() ) {
$details .= "****** 【 $name 】 ******* is final\n";
} if ( $method->isConstructor() ) {
$details .= "****** 【 $name 】 ******* is constructor\n";
} if ( $method->returnsReference() ) {
$details .= "****** 【 $name 】 ******* return a reference (as opposed to a value)\n";
} return $details;
} /**
* [getMethodSource 获取方法体]
* @param ReflectionMethod $method [反射方法对象]
* @return [type] [string]
*/
public function getMethodSource ( ReflectionMethod $method ) {
$path = $method->getFileName();
$lines = @file( $path );
$from = $method->getStartLine();
$to = $method->getEndLine();
$len = $to-$from+1;
return Implode( array_slice( $lines, $from-1, $len ));
}
}

在 getReflectionObj 这种方法里面大家可能已经注意到了。大家但是试试,有知道解决方式的交流下。。。。

这是我本地的截图:看着还是挺给力的,要是大家也想实现这样的效果,本地也弄一个krumo

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2pjMTk5MTExMTg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

利用反射api查找一个类的具体信息的更多相关文章

  1. C#利用反射,遍历获得一个类的所有属性名,以及该类的实例的所有属性的值

    转自goldeneyezhang原文 C#利用反射,遍历获得一个类的所有属性名,以及该类的实例的所有属性的值 C#利用反射,遍历获得一个类的所有属性名,以及该类的实例的所有属性的值总结: 对应某个类的 ...

  2. Android利用反射机制为实体类属性赋值

    在做android项目时,有时会遇到从网络上获取json类型数据,赋值给实体类,实体类属性少可以一个一个的赋值,如果实体类有很多属性,赋值可能就要耗很长的功夫了,幸好Java给我们提供了反射机制.下面 ...

  3. [转]C#利用反射实现两个类的对象之间相同属性的值的复制

    本文转自:https://blog.csdn.net/u013093547/article/details/53584591 在使用c#进行程序编写时,会遇到一个问题,两个属性字段差不多相同的类要进行 ...

  4. 利用反射实现Servlet公共类的抽取

    一次请求的执行过程: 请求:发送请求地址-->到达web.xml中,找到地址对应的servlet类-->通过反射调用该类的构造函数,创建该servlet类的对象-->通过当前对象调用 ...

  5. 利用system.reflection遍历一个类的变量成员

    假设有下面一个类,在程序中已初始化,如何获取里面的变量成员name,age,onduty及其值呢? public class Employee { public string name; public ...

  6. php反射机制获取未知类的详细信息

    使用ReflectionClass就可以获取未知类的详细信息 demo: require("hello.php"); $class = new ReflectionClass(&q ...

  7. php利用反射机制查找类和方法的所在位置

    //参数1是类名,参数2是方法名 $func = new ReflectionMethod('UnifiedOrder_pub', 'getPrepayId'); //从第几行开始 $start = ...

  8. C# 利用反射根据类名创建类的实例对象

    “反射”其实就是利用程序集的元数据信息. 反射可以有很多方法,编写程序时请先导入 System.Reflection 命名空间. 1.假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型): ...

  9. 【转】C# 利用反射根据类名创建类的实例对象

    原文地址:https://www.cnblogs.com/feiyuhuo/p/5793606.html “反射”其实就是利用程序集的元数据信息. 反射可以有很多方法,编写程序时请先导入 System ...

随机推荐

  1. C#编译器优化

    C#编译器优化 https://www.cnblogs.com/podolski/p/8987595.html 使用C#编写程序,给最终用户的程序,是需要使用release配置的,而release配置 ...

  2. HDU2080 夹角有多大2

    2019-05-17 15:00:09 加油加油,fightting !!! 这道题不知道acos()函数,acos()返回的是弧度,转化成度数要 / PI * 180 也没有想到通过向量 但是想到了 ...

  3. MySQL视图、触发器、事务、存储过程、函数

    视图.触发器.事务.存储过程.函数   阅读目录 一 视图 二 触发器 三 事务 四 存储过程 五 函数 六 流程控制 一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据 ...

  4. .net中的TreeView的数据绑定与EasyUi_tree的数据绑定

    昨天看到了.net中的TreeView,学习了一波TreeView的数据绑定,联想到EasyUi中的Tree的数据,觉得里面的逻辑差不多,就总结了一下两者的数据绑定. 前端页面和必要的JS如下 < ...

  5. 用 JS + LeanCloud 给网页添加数据库(留言功能)

    记录给自己网页添加留言功能的过程. 使用工具:LeanCloud,一个自带数据库和增删改查(CRUD)功能的后台系统. 1 在JS中引入LeanCloud官方库 在LeanCloud注册并添加应用的步 ...

  6. 关于原生app、webApp、混合app的介绍

    WebApp 原生App(Native App) 混合App(hybrid App) webApp: 用html5,css3 js开发的网页,运行在移动端的浏览器 zepto.angular.vue. ...

  7. angular实现的tab栏切换

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Android 用Handler和Message实现计时效果及其中一些疑问

    本来是打算继续做天气预报的优化的,但因为某些原因,我要先把之前做的小应用优化一下.所以今天就插播一下用Handler和Message实现计时效果. 首先,简要说明一下,这个应用有两个显示数字的Text ...

  9. MySQL 5.6 Reference Manual-14.3 InnoDB Transaction Model and Locking

    14.3 InnoDB Transaction Model and Locking 14.3.1 InnoDB Lock Modes 14.3.2 InnoDB Record, Gap, and Ne ...

  10. 【Oracle】创建用户

    任务: 1)创建用户siebel,密码oracle 2)授予sse_role,tblo_role角色 3)siebel用户没有对system,sysaux的使用权限 4)默认表空间ts_users,无 ...