zoukankan      html  css  js  c++  java
  • ThinkPHP 使用 SwaggerUi 自动生成 api 文档

    1、下载swagger-ui 

    GitHub地址:https://github.com/swagger-api/swagger-ui

    2、修改 ThinkPHP 的 build.php ,执行命令生成需要创建的模块

    // 定义api模块的自动生成 (按照实际定义的文件名生成)
        'api'     => [
            '__file__'   => ['common.php'],
            '__dir__'    => ['controller'],
            'controller' => ['Passport'],
            'model'      => [],
            'view'       => [],
        ],
    命令: php think build

    3、修改刚刚生成的模块下的 config.php 文件

    return [
        'default_return_type' => 'json', // 修改控制器默认输出json对象
        'url_param_type' => 1, // URL参数方式 0 按名称成对解析 1 按顺序解析
    ];

    4、在刚刚生成的 application/api/contorller/Passport.php 下添加这几个方法

    <?php
    namespace appapicontroller;
    
    /**
     * swagger: 登录相关
     */
    class Passport
    {
        /**
         * post: 发送验证码
         * path: sendVerify/{phone}/{deviceType}
         * method: sendVerify
         * param: phone - {string} 手机号
         * param: deviceType - {int} = [0|1|2|3|4] 设备类型(0: android手机, 1: ios手机, 2: android平板, 3: ios平板, 4: pc)
         */
        public function sendVerify($phone, $deviceType) {
            return [
                'code'        => 200,
                'message'    => '发送验证码',
                'data'        => [
                    'phone'            => $phone,
                    'deviceType'        => $deviceType
                ]
            ];
        }
        
        /**
         * post: 登陆
         * path: login
         * method: login
         * param: phone - {string} 手机号
         * param: password - {string} 密码
         * param: deviceType - {int} = [0|1|2|3|4] 设备类型(0: android手机, 1: ios手机, 2: android平板, 3: ios平板, 4: pc)
         * param: verifyCode - {string} = 0 验证码
         */
        public function login($phone, $password, $deviceType, $verifyCode = '0') {
            return [
                'code'        => 200,
                'message'    => '登陆成功',
                'data'        => [
                    'phone'            => $phone,
                    'password'        => $password,
                    'deviceType'        => $deviceType,
                    'verifyCode'        => $verifyCode
                ]
            ];
        }
        
        /**
         * get: 获取配置
         * path: profile
         * method: profile
         * param: keys - {string[]} 需要获取配置的Key值数组
         */
        public function profile($keys) {
            return [
                'code'        => 200,
                'message'    => '获取成功',
                'data'        => $keys
            ];
        }
    }

    5、把 swagger-ui 目录下的 dist 放到你的 public 目录下,然后更名为 swagger。

    6、修改 swagger 下 index.html 的路径:

        window.onload = function() {
          // Begin Swagger UI call region
          const ui = SwaggerUIBundle({
            url : window.location.href.replace(window.location.hash, "").replace(/[^/]+$/, "swagger.json"),
            dom_id: '#swagger-ui',
            deepLinking: true,
            presets: [
              SwaggerUIBundle.presets.apis,
              SwaggerUIStandalonePreset
            ],
            plugins: [
              SwaggerUIBundle.plugins.DownloadUrl
            ],
            layout: "StandaloneLayout"
          })
          // End Swagger UI call region
    
          window.ui = ui
        }

    7、整合ThinkPHP 和 swaggerUI:

    在 public 目录下新建 api.php 

    <?php
    
    // +----------------------------------------------------------------------
    // | ThinkPHP SWAGGER [ 够用就好 ]
    // +----------------------------------------------------------------------
    // | Copyright (c) 2016 http://jitlee.com All rights reserved.
    // +----------------------------------------------------------------------
    // | Licensed ( http://jitlee.com/licenses/LICENSE-1.0 )
    // +----------------------------------------------------------------------
    // | Author: Jitlee.Wan <www.wpj@163.com>
    // +----------------------------------------------------------------------
    
    // 定义应用目录
    define('APP_PATH', __DIR__ . '/../application');
    
    $tags = array(); // Tags对象
    $paths = array(); // Path数组
    
    $module_dir = opendir(APP_PATH);
    while (($module_name = readdir($module_dir)) !== false) {
        if ($module_name != 'api') continue; //可以自己设置需要哪些模块用作api输出页面
        $module_path = APP_PATH . DIRECTORY_SEPARATOR . $module_name;    //构建子目录路径
        if (is_dir($module_path)) {
            $module = strtolower($module_name);
    
            $module_child_dir = opendir($module_path);
            while (($module_child_name = readdir($module_child_dir)) !== false) {
                $module_child_path = $module_path . DIRECTORY_SEPARATOR . $module_child_name;    //构建子目录路径
                if (is_dir($module_child_path) && $module_child_name == 'controller') {
                    $controller_dir = opendir($module_child_path);
                    while (($controller_file = readdir($controller_dir)) !== false) {
                        $controller_path = $module_child_path . DIRECTORY_SEPARATOR . $controller_file;    //构建子目录路径
                        $controller_name = strtolower(basename($controller_path, '.php'));
                        $contents = file_get_contents($controller_path);
                        if (preg_match_all('/swagger:s*([^
    ]+)/i', $contents, $swagger_matches)) {
    
                            // 添加tag
                            $found_tag = false;
                            foreach ($tags as $tag) {
                                if ($tag['name'] == $controller_name) {
                                    $found_tag = true;
                                    break;
                                }
                            }
                            if (!$found_tag) {
                                array_push($tags, array(
                                    'name'            => $controller_name,
                                    'description'    => $swagger_matches[1][0]
                                ));
                            }
    
                            // 添加path
                            if (preg_match_all('//*((?!*/).)+*//s', $contents, $func_matches)) {
                                $length = count($func_matches[0]);
                                if ($length > 1) {
                                    for ($i = 1; $i < $length; $i++) {
                                        $func_array = array();
    
                                        // 解析每个方法
                                        $func_contents = $func_matches[0][$i];
    
                                        // 方法说明
                                        if (!preg_match_all('/(get|post|delete)s*:s*([^
    ]+)/i', $func_contents, $matches)) {
                                            break;
                                        }
                                        $method = $matches[1][0];
                                        $summary = $matches[2][0];
    
                                        // 路径
                                        if (!preg_match_all('/paths*:s*([^
    ]+)/i', $func_contents, $matches)) {
                                            break;
                                        }
                                        $path = $matches[1][0];
    
                                        // 方法名称
                                        $operations = explode('/', $path);
                                        $operationId = $operations[0];
                                        if (preg_match_all('/methods*:s*([^
    ]+)/i', $func_contents, $matches)) {
                                            $operationId = $matches[1][0];
                                        }
    
                                        $paths[$path] = array();
                                        $parameters = array();
                                        $func = array(
                                            'tags'            => [$controller_name],
                                            'summary'        => $summary,
                                            'description'    => '',
                                            'operationId'    => $operationId,
                                            'produces'        => ['application/json']
                                        );
    
                                        // 参数
                                        $pattern = '/params*:s*(?<name>w+)s*-s*{(?<type>w+(?<array>[])?)}s*(=s*(([(?<enum>[^]]+)])|(?<default>[^s]+))s*)?(?<summary>[^*]+)/i';
                                        if (preg_match_all($pattern, $func_contents, $matches)) {
                                            $names = $matches['name'];         // 参数名称
                                            $types = $matches['type'];         // 参数类型
                                            $enums = $matches['enum'];         // 参数枚举
                                            $defaults = $matches['default']; // 默认值
                                            $summarys = $matches['summary']; // 参数说明
                                            $arrays = $matches['array']; // 参数说明
    
                                            $params_count = count($names);
                                            for ($j = 0; $j < $params_count; $j++) {
                                                $in = $method == 'get' ? 'query' : 'formData';
                                                if (strpos($path, '{' . $names[$j] . '}') !== false) {
                                                    $in = 'path';
                                                }
    
                                                $parameter = array(
                                                    'name'            => $names[$j],
                                                    'in'                => $in,
                                                    'required'        => true,
                                                    'description'    => $summarys[$j]
                                                );
    
                                                if ($defaults[$j] !== '') {
                                                    $parameter['required'] = false;
                                                    $parameter['defaultValue'] = $defaults[$j];
                                                }
    
                                                $type = str_replace('[]', '', $types[$j]);
                                                if ($type == 'int') {
                                                    $type = 'integer';
                                                }
    
                                                if ($arrays[$j] != '') { // 是否数据参数
                                                    $parameter['type'] = 'array';
                                                    $parameter['items'] = array(
                                                        'type'    => str_replace('[]', '', $type)
                                                    );
                                                    $parameter['collectionFormat'] = 'brackets'; // url带中括号
                                                    //                                                $parameter['collectionFormat'] = 'multi'; // url不带中括号
                                                } else if ($enums[$j] != '') { // 是否枚举参数
                                                    $enum = explode('|', $enums[$j]);
                                                    $parameter['type'] = $type;
                                                    $parameter['enum'] = $enum;
                                                } else {
                                                    $parameter['type'] = $type;
                                                }
                                                array_push($parameters, $parameter);
                                            }
                                        }
                                        $func['parameters'] = $parameters;
                                        // 生成api访问路径
                                        $paths['/' . $module . '/' . $controller_name . '/' . $path][$method] = $func;
                                    }
                                }
                            }
                        }
                    }
                    closedir($controller_dir);
                }
            }
            closedir($module_child_dir);
        }
    }
    closedir($module_dir);
    
    $swagger = array(
        'swagger'    => '2.0',
        'info'        => array(
            'description'    => 'APP 后台服务',
            'version'        => '1.0.0',
            'title'            => '[我的APP]Swagger',
            'termsOfService' => 'http://www.ritacc.cn/',
            'contact'        => array(
                'email'        => 'www.wpj@163.com'
            ),
            'license'        => array(
                'name'        => 'Apache 2.0',
                'url'        => 'http://www.apache.org/licenses/LICENSE-2.0.html'
            )
        ),
        'host'        => $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'],
        'basePath'    => '',
        'tags'        => $tags,
        'schemes'    => [
            'http'
        ],
        'paths'        => $paths,
        'securityDefinitions' => array(),
        'definitions' => array(),
        'externalDocs' => array(
            'description'    => 'Find out more about Swagger',
            'url'            => 'http://swagger.io'
        )
    );
    
    $jsonFile = fopen("swagger/swagger.json", "w") or die("Unable to open file!");
    fwrite($jsonFile, json_encode($swagger));
    fclose($jsonFile);
    
    // 跳转到Swagger UI
    $url = '/swagger/index.html';
    Header('HTTP/1.1 303 See Other');
    Header("Location: $url");
    exit;

    8、打开浏览器运行 public 下的 api.php 就 ok 了。

  • 相关阅读:
    希尔排序算法
    直接插入排序和折半插入排序算法
    快排序算法
    部分博文目录索引(C语言+算法)
    Gnome排序算法
    选择排序算法
    pip运行报错Fatal error in launcher: Unable to create process using pip.exe
    Java Selenium封装--RemoteWebDriver
    Java Selenium封装--RemoteWebElement
    selenium webdriver自动化对日期控件的处理
  • 原文地址:https://www.cnblogs.com/xinchenhui/p/11732994.html
Copyright © 2011-2022 走看看