1、基于反射机制:实现注释生成文档
实现注释生成文档,主要是依赖反射机制获得成员函数的注释,然后基于注释的规范风格,进行参数切割(不建议使用正则表达式,因为效率太低),然后生成对应的html结构。
生成文档需要对注释风格编写是统一,并且规范才有可能实现,一旦不规范注释,就有可能生成错误。
具体的案例代码如下:
<?php# 测试用的A类class TestA {/*** 尼妹的* @author 小黄牛* @version v1.0.0.1* @deprecated v1.0.9.* 版本后弃用* @global 无* @todo 后期这个函数需要优化到神一样的执行速度* @param string $name 打死你* @param string $name 打死你* @param string $name 打死你* @return void*/public function orderBackA() {}/*** 你哥的* 这是一个给小黄牛用的函数,哈哈,不服你来打我啊** @author 小黄牛* @version v1.0.0.1* @deprecated v1.0.9.* 版本后弃用* @global 无* @todo 后期这个函数需要优化到神一样的执行速度* @param string $name 打死你* @param string $name 打死你* @param string $name 打死你* @return void*/private function orderBackB() {}}# 文档生成类class WordApi{private $_obj_Public;private $_obj_Private;private $_obj_Protected;private $_wordData;private $_length = 0;private $_wordGroup = ['@author' => '作者','@version' => '版本','@deprecated' => '废弃说明','@global' => '全局变量','@todo' => '优化建议','@param' => '参数','@return' => '返回值',];/*** 自动反射类** @param string $className 类名*/public function __construct($className) {# 使用ReflectionClass类$class = new ReflectionClass($className);# 获得成员函数$this->_obj_Public = $class->getMethods(ReflectionMethod::IS_PUBLIC);$this->_obj_Private = $class->getMethods(ReflectionMethod::IS_PRIVATE);$this->_obj_Protected = $class->getMethods(ReflectionMethod::IS_PROTECTED);# 自动触发解析$this->getFunction();$this->getNotes();}/*** 反射类下面的所有成员函数名称*/private function getFunction() {# 读取不同权限下的方法名称foreach ($this->_obj_Public as $method) {$this->_wordData[$this->_length]['obj'] = $method;$this->_wordData[$this->_length]['class'] = $method->class;$this->_wordData[$this->_length]['name'] = $method->name;$this->_wordData[$this->_length]['auto'] = ['控制权限', 'public'];$this->_length++;}foreach ($this->_obj_Private as $method) {$this->_wordData[$this->_length]['obj'] = $method;$this->_wordData[$this->_length]['class'] = $method->class;$this->_wordData[$this->_length]['name'] = $method->name;$this->_wordData[$this->_length]['auto'] = ['控制权限', 'private'];$this->_length++;}foreach ($this->_obj_Protected as $method) {$this->_wordData[$this->_length]['obj'] = $method;$this->_wordData[$this->_length]['class'] = $method->class;$this->_wordData[$this->_length]['name'] = $method->name;$this->_wordData[$this->_length]['auto'] = ['控制权限', 'protected'];$this->_length++;}}/*** 解析成员函数对应的注释内容*/private function getNotes() {foreach ($this->_wordData as $key=>$val) {# 获得成员函数对应的注释内容$note = $val['obj']->getDocComment();# 删除头尾标记(这里的第三个换行删除很重要)$note = str_replace(['/**', '*/', ''], '', $note);$note = explode(' *', $note);# 删除为空数组并更新键名索引$note = array_values(array_filter($note));foreach ($note as $k=>$v) {foreach ($this->_wordGroup as $kk=>$vv) {if (strrpos($v, $kk) !== false) {unset($this->_wordData[$key]['obj']); // 删除操作对象$name = str_replace('@', '', $kk);$this->_wordData[$key][$name][0] = $vv;$word = str_replace(" $kk ", '', $v);# 对一些标记元做特殊处理if (strrpos($v, '@param') !== false) {$array = explode(' ', $word);$this->_wordData[$key][$name][1][$k] = $array;} else {$this->_wordData[$key][$name][1] = $word;}} else {if ($k == 0) {$this->_wordData[$key]['title'][0] = '标题';$this->_wordData[$key]['title'][1] = $v;} else if ($k == 1) {$this->_wordData[$key]['des'][0] = '详情';if (strrpos($v, '@') === false) {$this->_wordData[$key]['des'][1] = $v;} else {$this->_wordData[$key]['des'][1] = '';}}}}}}}/*** 生成文档*/public function makeWord() {$table = "<br/>函数规范:<hr/><table><tr><td width='150'>标记元</td><td width='120'>说明</td><td>详细</td></tr>";$html = '';foreach ($this->_wordData as $key=>$val) {foreach ($val as $k=>$v) {if ($k == 'class') {$html .= "<h2>函数路径:$v -> ";} else if ($k == 'name') {$html .= "$v();</h2><hr/>";} else if ($k == 'auto') {$html .= '<h3>'.$v[0].':'.$v[1].'<h3/>';} else if ($k == 'title') {$html .= '<h3>'.$v[0].':'.$v[1].'<h3/>';if (empty($val['des'])) {$html .= $table;}} else if ($k == 'des') {$html .= '<h3>'.$v[0].':'.$v[1].'<h3/>'.$table;} else if ($k != 'param') {$html .= '<tr><td>@'.$k.'</td><td>'.$v[0].'</td><td>'.$v[1].'</td></tr>';}}$html .= '</table>';if (!empty($val['param'])) {$html .= "<br/>函数参数:<hr/><table><tr><td width='150'>变量名</td><td width='120'>类型</td><td>说明</td></tr>";foreach ($val['param'][1] as $k=>$v) {$html .= '<tr><td>'.$v[1].'</td><td>'.$v[0].'</td><td>'.$v[2].'</td></tr>';}$html .= '</table><hr/><br/>';}}echo $html;}}# 使用demo$obj = new WordApi('TestA');$obj->makeWord();
