<?php namespace Api\Doc; class Doc { protected $config = [ 'title' => 'APi接口文档', 'version' => '1.0.0', 'copyright' => '银河百荣科技', 'controller' => [ 'app\portal\controller\IndexController', 'app\escort\controller\EscortController', 'app\activity\controller\ActivityController', 'app\user\controller\CenterController', 'app\team\controller\TeamController', 'app\order\controller\OrderController', 'app\collect\controller\CollectController', 'app\news\controller\NewsController' ], 'password' => 'bronet', 'static_path' => '', 'filter_method' => ['_empty'], 'return_format' => [ 'code' => "状态码20000/40000+", 'msg' => "提示信息", ], 'public_header' => [], 'public_param' => [] ]; /** * 架构方法 设置参数 * @access public * @param array $config 配置参数 */ public function __construct($config = []) { $this->config = array_merge($this->config, $config); } /** * 使用 $this->name 获取配置 * @access public * @param string $name 配置名称 * @return mixed 配置值 */ public function __get($name) { return $this->config[$name]; } /** * 设置验证码配置 * @access public * @param string $name 配置名称 * @param string $value 配置值 * @return void */ public function __set($name, $value) { if (isset($this->config[$name])) { $this->config[$name] = $value; } } /** * 检查配置 * @access public * @param string $name 配置名称 * @return bool */ public function __isset($name) { return isset($this->config[$name]); } /** * 获取接口列表 * @return array */ public function getList() { $controller = $this->config['controller']; $list = []; foreach ($controller as $class) { if (class_exists($class)) { $module = []; $reflection = new \ReflectionClass($class); $doc_str = $reflection->getDocComment(); $doc = new DocParser(); $class_doc = $doc->parse($doc_str); $module = $class_doc; $module['class'] = $class; $method = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC); $filter_method = array_merge(['__construct'], $this->config['filter_method']); $module['actions'] = []; foreach ($method as $action) { if (!in_array($action->name, $filter_method)) { $doc = new DocParser(); $doc_str = $action->getDocComment(); if ($doc_str) { $action_doc = $doc->parse($doc_str); $action_doc['name'] = $class . "::" . $action->name; if (array_key_exists('title', $action_doc)) { if (array_key_exists('module', $action_doc)) { $key = array_search($action_doc['module'], array_column($module['actions'], 'title')); if ($key === false) { $action = $module; $action['title'] = $action_doc['module']; $action['module'] = $action_doc['module']; $action['actions'] = []; array_push($action['actions'], $action_doc); array_push($module['actions'], $action); } else { array_push($module['actions'][$key]['actions'], $action_doc); } } else { array_push($module['actions'], $action_doc); } } } } } if (array_key_exists('group', $module)) { $key = array_search($module['group'], array_column($list, 'title')); if ($key === false) { //创建分组 $floder = [ 'title' => $module['group'], 'description' => '', 'package' => '', 'class' => '', 'actions' => [] ]; array_push($floder['actions'], $module); array_push($list, $floder); } else { array_push($list[$key]['actions'], $module); } } else { array_push($list, $module); } } } return $list; } /** * 文档目录列表 * @return array */ public function getModuleList() { $controller = $this->config['controller']; $list = []; foreach ($controller as $class) { if (class_exists($class)) { $reflection = new \ReflectionClass($class); $doc_str = $reflection->getDocComment(); $doc = new DocParser(); $class_doc = $doc->parse($doc_str); if (array_key_exists('group', $class_doc)) { $key = array_search($class_doc['group'], array_column($list, 'title')); if ($key === false) { //创建分组 $floder = [ 'title' => $class_doc['group'], 'children' => [] ]; array_push($floder['children'], $class_doc); array_push($list, $floder); } else { array_push($list[$key]['children'], $class_doc); } } else { array_push($list, $class_doc); } } } return $list; } /** * 获取类中指导方法注释详情 * @param $class * @param $action * @return array */ public function getInfo($class, $action) { $action_doc = []; if ($class && class_exists($class)) { $reflection = new \ReflectionClass($class); $doc_str = $reflection->getDocComment(); $doc = new DocParser(); $class_doc = $doc->parse($doc_str); $class_doc['header'] = isset($class_doc['header']) ? $class_doc['header'] : []; $class_doc['param'] = isset($class_doc['param']) ? $class_doc['param'] : []; if ($reflection->hasMethod($action)) { $method = $reflection->getMethod($action); $doc = new DocParser(); $action_doc = $doc->parse($method->getDocComment()); $action_doc['name'] = $class . "::" . $method->name; $action_doc['header'] = isset($action_doc['header']) ? array_merge($class_doc['header'], $action_doc['header']) : $class_doc['header']; $action_doc['param'] = isset($action_doc['param']) ? array_merge($class_doc['param'], $action_doc['param']) : $class_doc['param']; } } return $action_doc; } /** * 文档列表搜素 * @param string $keyword * @return array */ public function searchList($keyword = "") { $controller = $this->config['controller']; $list = []; foreach ($controller as $class) { if (class_exists($class)) { $reflection = new \ReflectionClass($class); $method = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC); $filter_method = array_merge(['__construct'], $this->config['filter_method']); foreach ($method as $action) { if (!in_array($action->name, $filter_method)) { $doc = new DocParser(); $doc_str = $action->getDocComment(); if ($doc_str) { $action_doc = $doc->parse($doc_str); $action_doc['name'] = $class . "::" . $action->name; if ((isset($action_doc['title']) && strpos($action_doc['title'], $keyword) !== false) || (isset($action_doc['description']) && strpos($action_doc['description'], $keyword) !== false) || (isset($action_doc['author']) && strpos($action_doc['author'], $keyword) !== false) || (isset($action_doc['url']) && strpos($action_doc['url'], $keyword) !== false)) { array_push($list, $action_doc); } } } } } } return $list; } /** * 格式化数组为json字符串-用于格式显示 * @param array $doc * @return string */ public function formatReturn($doc = []) { $json = '{<br>'; $data = $this->config['return_format']; foreach ($data as $name => $value) { $json .= ' "' . $name . '":' . $value . ',<br>'; } $json .= ' "data":{<br/>'; $returns = isset($doc['return']) ? $doc['return'] : []; foreach ($returns as $val) { list($name, $value) = explode(":", trim($val)); if (strpos($value, '@') != false) { $json .= $this->string2jsonArray($doc, $val, ' '); } else { $json .= ' ' . $this->string2json(trim($name), $value); } } $json .= ' }<br/>'; $json .= '}'; return $json; } /** * 格式化json字符串-用于展示 * @param $name * @param $val * @return string */ private function string2json($name, $val) { if (strpos($val, '#') != false) { return '"' . $name . '": ["' . str_replace('#', '', $val) . '"],<br/>'; } else { return '"' . $name . '":"' . $val . '",<br/>'; } } /** * 递归转换数组为json字符格式-用于展示 * @param $doc * @param $val * @param $space * @return string */ private function string2jsonArray($doc, $val, $space) { list($name, $value) = explode(":", trim($val)); $json = ""; if (strpos($value, "@!") != false) { $json .= $space . '"' . $name . '":{//' . str_replace('@!', '', $value) . '<br/>'; } else { $json .= $space . '"' . $name . '":[{//' . str_replace('@', '', $value) . '<br/>'; } $return = isset($doc[$name]) ? $doc[$name] : []; if (preg_match_all('/(\w+):(.*?)[\s\n]/s', $return . " ", $meatchs)) { foreach ($meatchs[0] as $key => $v) { if (strpos($meatchs[2][$key], '@') != false) { $json .= $this->string2jsonArray($doc, $v, $space . ' '); } else { $json .= $space . ' ' . $this->string2json(trim($meatchs[1][$key]), $meatchs[2][$key]); } } } if (strpos($value, "@!") != false) { $json .= $space . "}<br/>"; } else { $json .= $space . "}]<br/>"; } return $json; } }