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

。。

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

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

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

  1. <?
  2.  
  3. php
  4. /**
  5. * use
  6. * $pros = new RefTools('calssname', true, false);
  7. * dpm($pros->Cinfo()); print_r($pros->Cinfo());
  8. */
  9. class RefTools {
  10. public $p_num;
  11. public $classname;
  12. public $isgetpar;
  13.  
  14. /**
  15. * [constructor 构造方法]
  16. * @param [type] $classname [类名]
  17. * @return [type] [null]
  18. */
  19. public function __construct($classname, $isgetpar=true){
  20. $this->classname = $classname;
  21. $this->p_num = 0;
  22. $this->isgetpar = $isgetpar;
  23. }
  24.  
  25. /**
  26. * [cInfo description]
  27. * @return [type] [description]
  28. */
  29. public function cInfo() {
  30. return $this->getClassMethod($this->classname);
  31. }
  32. /**
  33. * [getReflectionObj 获取反射对象]
  34. * @param [type] $classname [类名]
  35. * @return [type] [对象]
  36. */
  37. public function getReflectionObj($classname){
  38. //这里假设这样传參$this->classname,会导致运行时间太长而栈溢出,我的測试环境开启了xdebug,有xdebug.max_nesting_level=150
  39. //限制,可是通过传递參数就不会有此原因,知道的人一起交流交流
  40. return new ReflectionClass($classname);
  41. }
  42.  
  43. /**
  44. * [getClassMethod 获取类方法]
  45. * @param [type] $classname [类名]
  46. * @param boolean $isgetpar [是否继续查询父类]
  47. * @return [type] [数组]
  48. */
  49. public function getClassMethod($classname){
  50. $arr = array();
  51. //获取反射对象
  52. $pre = $this->getReflectionObj($classname);
  53. //获取反射对象的方法
  54. $methods = $pre->getMethods();
  55. $arr['tostring'] = $pre->__toString();
  56. $arr['classinfo'] = $this->getClassInfo($pre);
  57. $arr['Properties'] = $this->getPropertiesData($pre->getProperties());
  58. foreach ($methods as $key => $method) {
  59. $arr['method'][$method->getName()]['info'] = $this->getMethodData($method);
  60. $arr['method'][$method->getName()]['body'] = $this->getMethodSource($method);
  61. }
  62.  
  63. //是否获取父类
  64. if( $this->isgetpar ){
  65. $parclass = $pre->getParentClass();
  66. if(is_object($parclass)){
  67. $this->p_num++;
  68. $arr['parents'][$parclass->name] = $this->getClassMethod($parclass->name,true,false);
  69. }
  70. }
  71. $arr['parent_num'] = $this->p_num;
  72. return $arr;
  73. }
  74.  
  75. /**
  76. * [getClassInfo 获取类信息]
  77. * @param [type] $pre [反射类对象]
  78. * @return [type] [description]
  79. */
  80. public function getClassInfo($pre){
  81. $arr = array();
  82. $arr['path'] = $pre->getFileName();
  83. $arr['line'] = 'start:'.$pre->getStartLine().'****end:'.$pre->getEndLine();
  84. $arr['interface'] = $pre->getInterfaceNames();
  85. return $arr;
  86. }
  87.  
  88. /**
  89. * [getPropertiesDataa 获取属性信息]
  90. * @param [type] $properties [arr]
  91. * @return [type] [string]
  92. */
  93. public function getPropertiesData( $properties ){
  94. $arr = array();
  95. foreach ($properties as $key => $pp) {
  96. $pname = $pp->getName();
  97. $arr[$pname] = '****来自于 '.$pp->class.' 类****';
  98. }
  99. return $arr;
  100. }
  101.  
  102. /**
  103. * [getMethodData 获取类方法信息]
  104. * @param ReflectionMethod $method [方法对象]
  105. * @return [type] [string]
  106. */
  107. public function getMethodData( ReflectionMethod $method ){
  108. $details = '';
  109. $name = $method->getName();
  110. if ( $method->isUserDefined() ) {
  111. $details .= "****** 【 $name 】 ******* is user defined\n";
  112. }
  113.  
  114. if ( $method->isInternal() ) {
  115. $details .= "****** 【 $name 】 ******* is built-in\n";
  116. }
  117.  
  118. if ( $method->isAbstract() ) {
  119. $details .= "****** 【 $name 】 ******* is abstract\n";
  120. }
  121.  
  122. if ( $method->isPublic() ) {
  123. $details .= "****** 【 $name 】 ******* is public\n";
  124. }
  125.  
  126. if ( $method->isProtected() ) {
  127. $details .= "****** 【 $name 】 ******* is protected\n";
  128. }
  129.  
  130. if ( $method->isPrivate() ) {
  131. $details .= "****** 【 $name 】 ******* is private\n";
  132. }
  133.  
  134. if ( $method->isStatic() ) {
  135. $details .= "****** 【 $name 】 ******* is static\n";
  136. }
  137.  
  138. if ( $method->isFinal() ) {
  139. $details .= "****** 【 $name 】 ******* is final\n";
  140. }
  141.  
  142. if ( $method->isConstructor() ) {
  143. $details .= "****** 【 $name 】 ******* is constructor\n";
  144. }
  145.  
  146. if ( $method->returnsReference() ) {
  147. $details .= "****** 【 $name 】 ******* return a reference (as opposed to a value)\n";
  148. }
  149.  
  150. return $details;
  151. }
  152.  
  153. /**
  154. * [getMethodSource 获取方法体]
  155. * @param ReflectionMethod $method [反射方法对象]
  156. * @return [type] [string]
  157. */
  158. public function getMethodSource ( ReflectionMethod $method ) {
  159. $path = $method->getFileName();
  160. $lines = @file( $path );
  161. $from = $method->getStartLine();
  162. $to = $method->getEndLine();
  163. $len = $to-$from+1;
  164. return Implode( array_slice( $lines, $from-1, $len ));
  165. }
  166. }

在 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. LDA解决的问题

    人类是怎么生成文档的呢?LDA的这三位作者在原始论文中给了一个简单的例子.比如假设事先给定了这几个主题:Arts.Budgets.Children.Education,然后通过学习训练,获取每个主题T ...

  2. raspberry-常用命令

    安全关闭raspberry:sudo shutdown -h now 一次升级系统中的所有内容:sudo apt-get update 升级单个软件包:sudo apt-get install *** ...

  3. [JavaEE] Mybatis与Ibatis比较

    随着开发团队转投Google Code旗下,ibatis3.x正式更名为Mybatis 虽然从正式版发布至今也有近一年时间,官方也非常友好的提供了中文版的使用手册,不过相信很多人还在项目中使用ibat ...

  4. 最详细的CentOS 6与7对比(一):常见设置对比

    本主题将从3个角度进行对比 常见设置(CentOS 6 vs CentOS 7) 服务管理(Sysvinit vs Upstart vs Systemd) 性能测试(cpu/mem/io/oltp) ...

  5. 计算机网络自顶向下方法第2章-应用层(application-layer).2

    2.4 DNS:因特网的目录服务 2.4.1 DNS提供的服务 DNS的定义 实体层面看,DNS是一个由分层的DNS服务器实现的分布式数据库 协议层面看,DNS是一个使得主机能够查询分布式数据库的应用 ...

  6. C# 添加应用程序包

    项目中可能会遇到某些扩展方法不可以应用的情况,这时候需要在项目中引用程序包 步骤如下: 回车即可

  7. C#中的流_字节_字符_字符串之间的相互转换

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  8. JavaScript的并且&&

    <html> <head> <meta charset="utf-8"> <title>无标题文档</title> &l ...

  9. ibatis设置启用及关闭命名空间

    使ibatis用命名空间能够有效避免sql配置命名冲突,默认为启用状态,可以通过settings标签设置为关闭状态,例如: <settings> <setting name=&quo ...

  10. 01--数据结构——动态链表(C++)

    数据结构——动态链表(C++)   定义一个节点: [cpp] view plain copy   print? #include <iostream> using namespace s ...