利用反射api查找一个类的详细信息

    说到这个实例,首先介绍下本人,我是一个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

利用反射api查找一个类的详细信息

利用反射api查找一个类的详细信息利用反射api查找一个类的详细信息

利用反射api查找一个类的详细信息,布布扣,bubuko.com

利用反射api查找一个类的详细信息

上一篇:zatree插件优化:支持HTTP Basic Authorization认证访问zabbix API


下一篇:(2)window.load和ready的区别