1、swagger安装
第一步:安装swagger-ui前端
去这里下载https://github.com/swagger-api/swagger-ui
下载完成之后,将文件夹放到你的网站根目录上面,例如我是放在我wamp下面的www目录。
接着找到dist目录, 打开index.html把其中的那一串url改成自己的 比如http://localhost/tp/public/swagger.json
注意这个url就是后面swagger.json 的路径;
如果你想支持中文在index.html中加上
<script src=\'lang/translator.js\' type=\'text/javascript\'> </script><script src=\'lang/zh-cn.js\' type=\'text/javascript\'></script>
然后打开URL输入http://localhost/swagger-ui/dist/index.html
就可以看到前端界面了, 应该是没内容的, 因为还没生成swagger.json, 生成好之后你设置的URL就起了作用。swagger.json我是放在tp框架下的swagger-docs目录中的,具体路径看你自己,具体下面会提到,不要慌O(∩_∩)O~。
第二步:安装swagger-php后端
进入你的项目目录执行如下命令:
composer require zircote/swagger-php
提示安装完成后会在你tp项目的vendor中生成一个zircote的组件文件夹,说明已经安装插件成功了。
第三步:生成swagger.json文件
方法1、直接在命令行中输入:
php D:\Program\www\tp\vendor\zircote\swagger-php\bin\swagger D:\Program\www\tp\application\app\controller\ -o D:\Program\www\tp\public
注意:第一个路径是你安装成功后组件的路径; 第二个路径是你想要生成这个目录下所有用swagger方式注释的php文件,把所有注释生成api文档; 第三个路径是你存放生成swagger.json的路径
方法2、编写控制器方法生成swagger.json:
如果我们每次修改了api,还要手动执行第三步的代码,有些繁琐,那我们就在控制器中写一个方法,每次访问swagger-ui的时候自动执行,然后跳转到前台swagger界面中。
下面是控制器里面的方法
$path = \'../application\'; //你想要哪个文件夹下面的注释生成对应的API文档
$swagger = \Swagger\scan($path);
//header(\'Content-Type: application/json\');
//echo $swagger;
$swagger_json_path = $path.\'/swagger-docs/swagger.json\';
$res = file_put_contents($swagger_path, $swagger);
if ($res == true) {
$this->redirect(\'http://localhost/swagger-ui/dist/index.html\');
}
第四步:编写swagger注释
控制器的注释写法
/** * @SWG\Resource( * basePath="http://skyapi.dev", * resourcePath="/vps", * @SWG\Api( * path="/vps", * @SWG\Operation( * method="GET", * type="array", * summary="Fetch vps lists", * nickname="vps/index", * @SWG\Parameter( * name="expand", * description="Models to expand", * paramType="query", * type="string", * defaultValue="vps,os_template" * ) * ) * ) * ) */ class VpsController extends Controller { // ... }
这只是个简单的实例具体的注释写法请自己百度
2、swagger注释使用
参考这个(写的比较全面):https://learnku.com/laravel/t/7430/how-to-write-api-documents-based-on-swagger-php#747b67
还有这个:https://blog.csdn.net/dyt19941205/article/details/79025266
这个:https://www.jianshu.com/p/554cd3762ab1
结合上面这几篇文章学习写了一个借口文档,也就四个方法,基本需要的东西都有了,以后再写文档可以照搬了
写接口文档真的很费时间,尤其写在php注释里,比较简单的文档可以使用swagger提供的编辑工具,直接在上面修改json文件后导出使用就可以了:http://editor.swagger.io/
下面给一个完整的接口注释:
<?php namespace app\app\controller; use think\Controller; use think\Request; use think\Db; /** * @SWG\Swagger( * schemes={"http"}, * host="127.0.0.1", * basePath="/restudy/public/index.php/app/", * consumes={"multipart/form-data","X-Requested-With/XMLHttpRequest"}, * produces={"application/json"}, * @SWG\Info( * version="1.0", * title="我的测试学习api项目", * description="接口学习,目前只写了一个Api类,把*栏目接口、二级栏目接口、文章列表接口、文章内容接口写到了一起" * ), * * @SWG\Tag( * name="Api", * description="新闻webapp四大接口", * ), * ) */ class Api extends Controller { /** *@SWG\Get(path="/api/gettopnav", tags={"Api"}, * summary="获取*栏目列表", * description="获取*栏目列表,返回栏目id,名称,和是否启用栏目", @SWG\Parameter( * description="ajax请求要加上X-Requested-With:XMLHttpRequest头字段", * format="string", * in="header", * name="X-Requested-With", * required=true, * type="string", default="XMLHttpRequest", * * ), @SWG\Response(response="200", description="操作成功", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=200, * ), * @SWG\Property( * property="msg", * type="string", example="*栏目返回成功", * ), @SWG\Property( * property="data", * type="object", example="[{cate_id:5,cate_name:\'栏目1\',cate_ison:1},{cate_id:6,cate_name:\'栏目2\',cate_ison:0}]", * ), * * )), @SWG\Response(response="201", description="数据为空", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=201, * ), * @SWG\Property( * property="msg", * type="string", example="数据为空!", * ), * * )), @SWG\Response(response="400", description="非法请求,不是ajax请求", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=400, * ), * @SWG\Property( * property="msg", * type="string", example="非法请求", * ), * * )), * ) */ //*栏目接口 public function getTopnav(){ if(request()->isAjax()){ $data=Db::table(\'re_cate\')->where(\'cate_pid\',0)->field(\'cate_id,cate_name,cate_ison\')->select(); if(!empty($data)){ return json([\'code\'=>200,\'msg\'=>\'*栏目返回成功\',\'data\'=>$data]); }else{ return json([\'code\'=>201,\'msg\'=>\'数据为空!\']); } }else{ return json([\'code\'=>400,\'msg\'=>\'非法请求\']); } } /** *@SWG\Post(path="/api/getsonnav", tags={"Api"}, * summary="获取二级栏目列表", * description="根据栏目id获取二级栏目列表,返回栏目id,名称,和是否启用栏目", @SWG\Parameter( * description="ajax请求要加上X-Requested-With:XMLHttpRequest头字段", * format="string", * in="header", * name="X-Requested-With", * required=true, * type="string", default="XMLHttpRequest", * * ), * @SWG\Parameter(name="id",type="integer", required=true, in="formData", * description="*栏目id" * ), @SWG\Response(response="200", description="操作成功", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=200, * ), * @SWG\Property( * property="msg", * type="string", example="二级栏目返回成功", * ), @SWG\Property( * property="data", * type="object", example="[{cate_id:5,cate_name:\'栏目1\',cate_ison:1},{cate_id:6,cate_name:\'栏目2\',cate_ison:0}]", * ), * * )), @SWG\Response(response="201", description="数据为空", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=201, * ), * @SWG\Property( * property="msg", * type="string", example="数据为空!", * ), * * )), @SWG\Response(response="400", description="非法请求,不是ajax请求", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=400, * ), * @SWG\Property( * property="msg", * type="string", example="非法请求", * ), * * )), * ) */ //二级栏目接口 public function getSonnav(){ if(request()->isAjax()){ $cate_id=input(\'id\'); $data=Db::table(\'re_cate\')->where(\'cate_pid\',$cate_id)->field(\'cate_id,cate_name,cate_ison\')->select(); if(!empty($data)){ return json([\'code\'=>200,\'msg\'=>\'二级栏目返回成功\',\'data\'=>$data]); }else{ return json([\'code\'=>201,\'msg\'=>\'无二级栏目\']); } }else{ return json([\'code\'=>400,\'msg\'=>\'非法请求\']); } } /** *@SWG\Post(path="/api/getarticlelist", tags={"Api"}, * summary="获取文章列表", * description="根据栏目id获取文章列表(需要参数:栏目id,页码,一页显示文章数量)", @SWG\Parameter( * description="ajax请求要加上X-Requested-With:XMLHttpRequest头字段", * format="string", * in="header", * name="X-Requested-With", * required=true, * type="string", default="XMLHttpRequest", * * ), * @SWG\Parameter(name="id",type="integer", required=true, in="formData", * description="栏目id" * ), @SWG\Parameter(name="p",type="integer", required=true, in="formData", * description="页码" * ), @SWG\Parameter(name="num",type="integer", required=true, in="formData", * description="每页文章数量" * ), @SWG\Response(response="200", description="操作成功", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=200, * ), * @SWG\Property( * property="msg", * type="string", example="文章列表返回成功", * ), @SWG\Property( * property="data", * type="object", example="{total:null,per_page:5,current_page:1,last_page:null,data:[{ar_id:1,cate_id:10,ar_title:\'文章标题一\',ar_keywords:\'文章关键字\',ar_pic:\'url\',ar_content:\'文章内容\',ar_ison:1}]}", * ), * * )), @SWG\Response(response="201", description="数据为空", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=201, * ), * @SWG\Property( * property="msg", * type="string", example="数据为空!", * ), * * )), @SWG\Response(response="400", description="非法请求,不是ajax请求", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=400, * ), * @SWG\Property( * property="msg", * type="string", example="非法请求", * ), * * )), * ) */ //指定栏目文章列表(需要参数:栏目id,页码,一页显示文章数量) /* 返回json格式 { "code": 200, "msg": "文章返回成功", "data": { "total": null, "per_page": "1", "current_page": 1, "last_page": null, "data": [ { "ar_id": 1, "cate_id": 10, "ar_title": "title", "ar_keywords": "k,e,y", "ar_pic": "public/static/uploads/20190902\\98edeb3d27fe4342da8b07d5ae3e98de.jpg", "ar_content": "<p>内容<br/></p>", "ar_ison": 1 } ] } } */ public function getArticlelist(){ if(request()->isAjax()){ $cate_id=input(\'id\'); $page=input(\'p\'); $number=input(\'num\'); $data=Db::table(\'re_article\')->where(\'cate_id\',$cate_id)->paginate($number,true,[\'page\'=>$page]); if(!empty($data)){ return json([\'code\'=>200,\'msg\'=>\'文章返回成功\',\'data\'=>$data]); }else{ return json([\'code\'=>201,\'msg\'=>\'没有数据了\']); } }else{ return json([\'code\'=>400,\'msg\'=>\'非法请求\']); } } /** *@SWG\Post(path="/api/getarticlecontent", tags={"Api"}, * summary="获取文章内容", * description="根据文章id获取文章信息", @SWG\Parameter( * description="ajax请求要加上X-Requested-With:XMLHttpRequest头字段", * format="string", * in="header", * name="X-Requested-With", * required=true, * type="string", default="XMLHttpRequest", * * ), * @SWG\Parameter(name="id",type="integer", required=true, in="formData", * description="文章id" * ), @SWG\Response(response="200", description="操作成功", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=200, * ), * @SWG\Property( * property="msg", * type="string", example="文章返回成功", * ), @SWG\Property( * property="data", * type="object", example="{ar_id:1,ar_title:\'文章1\',ar_pic:\'url\',ar_keywords:\'文章关键字\',ar_content:\'文章内容\',ar_ison:1}", * ), * * )), @SWG\Response(response="201", description="数据为空", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=201, * ), * @SWG\Property( * property="msg", * type="string", example="数据为空!", * ), * * )), @SWG\Response(response="400", description="非法请求,不是ajax请求", @SWG\Schema( * required={""}, * @SWG\Property( * property="code", * type="integer", example=400, * ), * @SWG\Property( * property="msg", * type="string", example="非法请求", * ), * * )), * ) */ //获取指定文章内容 public function getArticlecontent(){ if(request()->isAjax()){ $ar_id=input(\'id\'); $data=Db::table(\'re_article\')->where(\'ar_id\',$ar_id)->find(); if(!empty($data)){ return json([\'code\'=>200,\'msg\'=>\'文章返回成功\',\'data\'=>$data]); }else{ return json([\'code\'=>201,\'msg\'=>\'无此文章\']); } }else{ return json([\'code\'=>400,\'msg\'=>\'非法请求\']); } } }