通过php中的反射机制,获取该类的文档注释,再通过获取其所有的方法,获取方法的注释

所用到的主要类及其方法

ReflectionClass
ReflectionClass::getDocComment
ReflectionClass::getMethods $method->getName()
$method->getDocComment();
$method->isProtected();
$method->getParameters(); $param->getName();
$param->isDefaultValueAvailable();
$param->getDefaultValue()

测试类如下:

test.php

<?php
header("Content-type: text/html; charset=utf-8");
require_once dir(__DIR__).'function.php';
require_once dir(__DIR__).'TestClass.php'; $class_name = 'TestClass'; $reflection = new ReflectionClass ( $class_name );
//通过反射获取类的注释
$doc = $reflection->getDocComment ();
//解析类的注释头
$parase_result = DocParserFactory::getInstance()->parse ( $doc );
$class_metadata = $parase_result; //输出测试
var_dump ( $doc );
echo "\r\n";
print_r( $parase_result );
echo "\r\n-----------------------------------\r\n"; //获取类中的方法,设置获取public,protected类型方法
$methods = $reflection->getMethods(ReflectionMethod::IS_PUBLIC + ReflectionMethod::IS_PROTECTED + ReflectionMethod::IS_PRIVATE);
//遍历所有的方法
foreach ($methods as $method) {
//获取方法的注释
$doc = $method->getDocComment();
//解析注释
$info = DocParserFactory::getInstance()->parse($doc);
$metadata = $class_metadata + $info;
//获取方法的类型
$method_flag = $method->isProtected();//还可能是public,protected类型的
//获取方法的参数
$params = $method->getParameters();
$position=0; //记录参数的次序
foreach ($params as $param){
$arguments[$param->getName()] = $position;
//参数是否设置了默认参数,如果设置了,则获取其默认值
$defaults[$position] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : NULL;
$position++;
} $call = array(
'class_name'=>$class_name,
'method_name'=>$method->getName(),
'arguments'=>$arguments,
'defaults'=>$defaults,
'metadata'=>$metadata,
'method_flag'=>$method_flag
);
print_r($call);
echo "\r\n-----------------------------------\r\n";
}

function.php

<?php
require_once dir(__DIR__).'DocParser.php'; /**
* 解析doc
* 下面的DocParserFactory是对其的进一步封装,每次解析时,可以减少初始化DocParser的次数
*
* @param $php_doc_comment
* @return array
*/
function parse_doc($php_doc_comment) {
$p = new DocParser ();
return $p->parse ( $php_doc_comment );
} /**
* Class DocParserFactory 解析doc
*
* @example
* DocParserFactory::getInstance()->parse($doc);
*/
class DocParserFactory{ private static $p;
private function DocParserFactory(){
} public static function getInstance(){
if(self::$p == null){
self::$p = new DocParser ();
}
return self::$p;
} }

TestClass.php

<?php
/**
* A test class 在此处不能添加@ur,@param,@return 注释
 * 如果要将类的注释和方法的注释合并的话,添加了上面的注释,会将方法中的注释给覆盖掉
*/
class TestClass {
/**
* @desc 获取public方法
*
* @url GET pnrs
* @param array $request_data
* @return int id
*/
public function getPublicMethod($no_default,$add_time = '0000-00-00') {
echo "public";
}
/**
* @desc 获取private方法
*
* @url GET private_test
* @return int id
*/
private function getPrivateMethod($no_default,$time = '0000-00-00') {
echo "private";
} /**
* @desc 获取protected方法
*
* @url GET protected_test
* @param $no_defalut,$time
* @return int id
*/
protected function getProtectedMethod($no_default,$time = '0000-00-00') {
echo "protected";
}
}

DocParser.php  该类源自一个开源项目

<?php
/**
* Parses the PHPDoc comments for metadata. Inspired by Documentor code base
* @category Framework
* @package restler
* @subpackage helper
* @author Murray Picton <info@murraypicton.com>
* @author R.Arul Kumaran <arul@luracast.com>
* @copyright 2010 Luracast
* @license http://www.gnu.org/licenses/ GNU General Public License
* @link https://github.com/murraypicton/Doqumentor
*/
class DocParser {
private $params = array ();
function parse($doc = '') {
if ($doc == '') {
return $this->params;
}
// Get the comment
if (preg_match ( '#^/\*\*(.*)\*/#s', $doc, $comment ) === false)
return $this->params;
$comment = trim ( $comment [1] );
// Get all the lines and strip the * from the first character
if (preg_match_all ( '#^\s*\*(.*)#m', $comment, $lines ) === false)
return $this->params;
$this->parseLines ( $lines [1] );
return $this->params;
}
private function parseLines($lines) {
foreach ( $lines as $line ) {
$parsedLine = $this->parseLine ( $line ); // Parse the line if ($parsedLine === false && ! isset ( $this->params ['description'] )) {
if (isset ( $desc )) {
// Store the first line in the short description
$this->params ['description'] = implode ( PHP_EOL, $desc );
}
$desc = array ();
} elseif ($parsedLine !== false) {
$desc [] = $parsedLine; // Store the line in the long description
}
}
$desc = implode ( ' ', $desc );
if (! empty ( $desc ))
$this->params ['long_description'] = $desc;
}
private function parseLine($line) {
// trim the whitespace from the line
$line = trim ( $line ); if (empty ( $line ))
return false; // Empty line if (strpos ( $line, '@' ) === 0) {
if (strpos ( $line, ' ' ) > 0) {
// Get the parameter name
$param = substr ( $line, 1, strpos ( $line, ' ' ) - 1 );
$value = substr ( $line, strlen ( $param ) + 2 ); // Get the value
} else {
$param = substr ( $line, 1 );
$value = '';
}
// Parse the line and return false if the parameter is valid
if ($this->setParam ( $param, $value ))
return false;
} return $line;
}
private function setParam($param, $value) {
if ($param == 'param' || $param == 'return')
$value = $this->formatParamOrReturn ( $value );
if ($param == 'class')
list ( $param, $value ) = $this->formatClass ( $value ); if (empty ( $this->params [$param] )) {
$this->params [$param] = $value;
} else if ($param == 'param') {
$arr = array (
$this->params [$param],
$value
);
$this->params [$param] = $arr;
} else {
$this->params [$param] = $value + $this->params [$param];
}
return true;
}
private function formatClass($value) {
$r = preg_split ( "[\(|\)]", $value );
if (is_array ( $r )) {
$param = $r [0];
parse_str ( $r [1], $value );
foreach ( $value as $key => $val ) {
$val = explode ( ',', $val );
if (count ( $val ) > 1)
$value [$key] = $val;
}
} else {
$param = 'Unknown';
}
return array (
$param,
$value
);
}
private function formatParamOrReturn($string) {
$pos = strpos ( $string, ' ' ); $type = substr ( $string, 0, $pos );
return '(' . $type . ')' . substr ( $string, $pos + 1 );
}
}

转: https://blog.csdn.net/my_yang/article/details/43882661

php反射获取类和方法中的注释的更多相关文章

  1. Java反射学习-1 - 反射获取类的属性,方法,构造器

    新建一个Person类 package cn.tx.reflect; /** * 注解初步了解 * @author Administrator * */ public class Person { p ...

  2. java反射-使用反射获取类的所有信息

    在OOP(面向对象)语言中,最重要的一个概念就是:万事万物皆对象. 在java中,类也是一个对象,是java.lang.Class的实例对象,官网称该对象为类的类类型. Class 类的实例表示正在运 ...

  3. Java反射学习-3 - 反射获取属性,方法,构造器

    package cn.tx.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import ...

  4. java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包

    首先自定义三个类 package reflection1; public interface MtInterface { void info(); } package reflection1; imp ...

  5. c#通过反射获取类上的自定义特性

    c#通过反射获取类上的自定义特性 本文转载:http://www.cnblogs.com/jeffwongishandsome/archive/2009/11/18/1602825.html 下面这个 ...

  6. java利用反射获取类的属性及类型

    java利用反射获取类的属性及类型. import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Map ...

  7. c++ 类覆盖方法中的协变返回类型

    c++ 类覆盖方法中的协变返回类型 在C++中,只要原来的返回类型是指向类的指针或引用,新的返回类型是指向派生类的指针或引用,覆盖的方法就可以改变返回类型.这样的类型称为协变返回类型(Covarian ...

  8. C#通过反射调用类及方法

    反射有个典型的应用,就是菜单的动态加载,原理就是通过反射调用某个窗体(类).下面演示一下通过反射调用类及方法: 1.新建一个类,命名为:ReflectionHelper,代码如下: #region 创 ...

  9. idea中查看方法参数;查看类、方法、属性注释

    Ctrl+P:查看方法参数Ctrl+Q:查看类.方法.属性注释

随机推荐

  1. 转:nginx基础概念(keepalive、pipe)

    keapalive 当然,在nginx中,对于http1.0与http1.1也是支持长连接的.什么是长连接呢?我们知道,http请求是基于TCP协议之上的,那么,当客户端在发起请求前,需要先与服务端建 ...

  2. [转] Compile、Make和Build的区别

    针对Java的开发工具,一般都有Compile.Make和Build三个菜单项,完成的功能的都差不多,但是又有区别.   编译,是将源代码转换为可执行代码的过程.编译需要指定源文件和编译输出的文件路径 ...

  3. SSH使用Log4j

    1. 将Jar文件log4j-1.2.14.jar导入项目. 2. 在src文件夹下新建log4j.properties文件: log4j.rootLogger = debug,stdout,D,E ...

  4. Mongostat 3.0详解

    可以参考之前写的这篇博客: Mongostat 2.6详解 mapped Changed in version 3.0.0. Only for MMAPv1 Storage Engine. The t ...

  5. vue框架整体流程

    1.整体流程 (1)模板解析成render函数 (2)响应式监听 (3)首次渲染,显示页面,绑定依赖 (4)data属性变化,触发rerender 2.模板解析为render函数 参考上一篇博客. 模 ...

  6. sqlserver 建表语句,获取建表语句的存储过程,包括排序规则,索引,字段说明,支持同时生成多个表

    先创建一个分割表名的分割函数 --表值函数用以截取字符串 --如果为其添加一列主键id,则其顺序就会固定了 create FUNCTION [Split](@text NVARCHAR(max)) ) ...

  7. SWF运行时判断两个DisplayObject是否同个类型,属于flash professional库中的同一个元件

    一般我们判断两个实例对象是否同样的类型,可以用typeof得到对象类型,然后用==号比较. typeof适用于原生类型. 而对于自定义类型,虽然typeof得到的都是Object,但还有更强的招数:g ...

  8. 多表连接的三种方式详解 hash join、merge join、 nested loop

    在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式.多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪 ...

  9. 小贝_mysql 触发器使用

    触发器 简要 1.触发器基本概念 2.触发器语法及实战样例 3.before和after差别 一.触发器基本概念 1.一触即发 2.作用: 监视某种情况并触发某种操作 3.观察场景 一个电子商城: 商 ...

  10. oracle 拼接字符串的两种方式

      方式一:使用管道符||进行拼接 方式二:使用concat()函数 区别: 方式一可以拼接多个字符串:方式二只能将2个字符串拼接到一起. 写在最后 哪位大佬如若发现文章存在纰漏之处或需要补充更多内容 ...