php自写api文档生成工具

框架改版后的第二个版本定下来了,这两天也比较轻松,于是就折腾给项目建个好看的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
				
   
   
				 href="/asset/css/layui.css" rel="stylesheet"/>
				 href="/asset/css/common.css" rel="stylesheet"/>
				
			
			
				
   
   
				
   
   
%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。

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值