php自写api文档生成工具

来源:互联网 发布:知乎45个神回复 编辑:程序博客网 时间:2024/05/16 14:35

框架改版后的第二个版本定下来了,这两天也比较轻松,于是就折腾给项目建个好看的api文档。

各种折腾。先是折腾phpDocumentor2,用phpdoc开源工具来建立文档,好不容易安装成功,各个模板都使用了一遍,还是不满意。后来又发现了swagger文档生成工具,起初看起来还蛮直观的,但是一看注释块,又觉得太繁琐了。

索性,主管拍板,自己写一个api文档生成类,满足自己的需求:体现路由,方法和参数。

自写工具的优点是:高可定制化,满足自己的一切要求,实现自己想要的样式,没有冗余文件

下面是注释块样式:

/** * @description 这里是描述 * @router http://www.test.com/api/demo/:id * @method GET * @param string $a * @param string $b * @return number */

下面是生成的效果 图:


实现代码如下:

/** * 1.以输入的目录分目录,proxy,user,site * 2.以@package分文件,site.html,vhost.html  */class apiDoc{static $round = 1;static $testArr = array();static $docPackage = '';public static function targetApiDir($dir){$apiDir = API_PATH.$dir."/";self::$docPackage = API_DOC_DIR.$dir;self::parseApiFile($apiDir);}public static function parseApiFile($dir){$arr = scandir($dir);foreach ($arr as $v) {if ($v == "." || $v == "..") {continue;}$file = $dir.$v;$content = file_get_contents($file);$preg = "/\/\*[\S\s]+?\*\//";preg_match_all($preg,$content,$rows);if (!!$rows) {foreach ($rows[0] as $key=>$row) {$arr = self::doWithBlocQuote($row);self::$testArr[$arr['package']][$arr['router']."-".$arr['method']] = $arr;}}}if (self::unitDocDir(API_DOC_DIR)) {self::createDocHtml();}echo "创建成功";print_r(self::$testArr);}private static function doWithBlocQuote($row){$router = "";$param = array();$method = '';$package = '';$return = '';$description = '';$preg_router = "/@router[\S\s]+?\\n/";if (preg_match($preg_router, $row)) {$arr= explode("\n", $row);foreach ($arr as $a) {$a = trim($a);$a = trim($a,"*");$a = trim($a,"\t");$a = trim($a,"\n");if ($a == "/" || !$a) {continue;}$a = preg_replace('/\s(?=\s)/', '\\1', ltrim($a, " "));$b = explode(" ", $a);if ($b[0] == "@description" && count($b) >= 2) {$b[1] = self::contactRemains($b, 2);$description = $b[1];}if ($b[0] =="@package" && count($b) >= 2) {$package = $b[1];}if ($b[0] == "@router") {$router = $b[1];}if ($b[0] =="@method") {$method = $b[1];}if ($b[0] =="@param" && count($b) >= 3) {$b[3] = self::contactRemains($b, 4);array_push($param, array("type"=>$b[1],"name"=>$b[2], "description"=>$b[3]));}if ($b[0] =="@return") {$return = $b[1];}}return array('description'=>$description,'package' => $package,'router' => $router,'method' => $method,'param' => $param,'return' => $return);}}private static function headHtml($title, $content){$tpl = '%s.layui-form-label, .layui-form-mid, .layui-table th, .layui-table td{padding-bottom:5px;padding-top:5px;}.layui-form{padding-bottom:10px;margin-bottom:10px;}
%s

© 2013 %s, Inc. All rights reserved.

';return sprintf($tpl,$title, $content, $title);}private static function createContentHtml($descript, $router, $method, $params){$paramHtml = '';if (count($params) > 0) {foreach ($params as $param) {$paramHtml.= sprintf('%s%s%s', $param['name'], $param['type'], $param['description']);}} else {$paramHtml = '无';}$html = '
%s
%s
%s
参数类型参数说明 %s
';return sprintf($html, $descript, $router, $method, $paramHtml);}private static function createDocHtml(){foreach (self::$testArr as $package=>&$list) {ksort($list);$html = '';foreach ($list as $k=>$v) {$html.= self::createContentHtml($v['description'], $v['router'], $v['method'], $v['param']);}$webname = sessionGet("web_name");if (!$webname) {$webname = SystemMod::webName();}self::createDocTempFile($package, self::headHtml($webname, $html));}}private static function contactRemains($arr, $remains){$str = '';if (count($arr) >= $remains) {$str = '';for ($i = $remains - 1; $i < count($arr);$i++){$str.= $arr[$i];}}return $str;}private static function createDocTempFile($package, $content, $filename = null){if (!is_dir(self::$docPackage)) {mkdir(self::$docPackage, 775, true);}$newFile = self::$docPackage."/".$package.".html";file_put_contents($newFile, $content.PHP_EOL, FILE_APPEND);}private static function unitDocDir($dir){$arr = scandir($dir);foreach ($arr as $v) {if ($v == "." || $v == "..") {continue;}$subDir = $dir."/".$v;if (is_file($subDir)) {unlink($subDir);} else {if (count(scandir($subDir)) > 2) {self::unitDocDir($subDir);}rmdir($subDir);}}return true;}}

以上是上线代码,通过给定api扫描目录生成文档目录,再以定义的package为文件名,生成文档文件。例如;如果文档目录是http://www.test.com/api/demo,则程序会自动扫描demo目录下的所有php文件,并根据注释块解析package, router, method, param,return等内容,如package为demo2,则会生成demo2.html文件,目录为http://www.test.com/doc/demo/demo2.html。

自工作以后,一直都在做工作的事情,也很少用到文本处理函数 。这次写这个工具类,又让我重温了一边文件创建及删除,还是蛮酷的。