ThinkPHP 6.0 不解析 @api 等注解,需用 swagger-php 工具解析 @OA\Get 等 OpenAPI 注解生成文档;path 必须与 Route::get() 注册路径完全一致,且需正确配置 Swagger UI 才能展示交互式文档。

TP6 不认 @api 注解,别白写了
ThinkPHP 6.0 本身完全不解析任何 @api、@param、@return 这类注释——它们只是普通 PHP 注释,框架压根不会读。所谓“自动生成文档”,实际依赖的是 zircote/swagger-php 这个独立工具,它按 OpenAPI 3.0 标准解析 @OA\Get 等注解,再导出 JSON/YAML。
常见错误包括:
- 在控制器方法上写
@api或@param,结果生成空文件或报错Warning: No operations defined - 混用 ThinkPHP 5.1 的
think-apidoc插件(已废弃,不兼容 TP6) - 注解没放在
/** */块里,或者和方法之间隔了空行
@OA\Get 的 path 必须和路由注册完全一致
Swagger-PHP 不关心你的控制器路径或方法名,只认你通过 Route::get() 实际注册的 URL 路径。写错 path 就会导致接口不显示,或生成后 UI 里点击 404。
比如你在 route/app.php 里写了:
Route::get('api/v1/users', 'UserController@index');那么注解必须是:
/** * @OA\Get( * path="/api/v1/users", * summary="获取用户列表" * ) */
而不是 /users、/index、api/v1/users(缺开头斜杠)或 /api/v1/users/(结尾多斜杠)。
其他要点:
-
@OA\Post、@OA\Put同理,path必须和Route::post()注册的路径一字不差 - 路径中带变量的,如
Route::get('api/v1/users/{id}', ...),注解里写path="/api/v1/users/{id}",并补上@OA\Parameter - 所有
@OA\*注解必须用use OpenApi\Annotations as OA;导入命名空间
生成 openapi.json 的两种可靠方式
推荐优先用命令行生成,稳定可控;动态路由方式容易因环境或缓存导致 JSON 内容陈旧。
方式一:终端执行(项目根目录)
./vendor/bin/openapi app/controller -o public/openapi.json
说明:
-
app/controller是默认扫描路径,如有model或service里也写了接口定义,可追加路径:app/controller app/model -
-o指定输出位置,建议放public/下,方便 Web 直接访问 - PHP 版本需 ≥ 7.4(
swagger-php 4.x强制要求)
方式二:加一个静态路由返回 JSON(仅开发调试用)
Route::get('api-docs', function () {
return json_decode(file_get_contents(public_path('openapi.json')), true);
});注意:不要用 file_get_contents 动态扫描源码生成,性能差且易出错;JSON 文件应由 CI/CD 或部署脚本预生成。
前端展示用 Swagger UI,不是“装个插件”就完事
生成 openapi.json 只是第一步;要看到带交互界面的漂亮文档,还得把 Swagger UI 静态资源放到 public/ 下,并配好入口 HTML。
最简做法(无需 Node.js):
- 下载
swagger-ui-dist的最新版 ZIP(如 v5.17.14),解压后把dist/里所有文件放进public/swagger/ - 新建
public/swagger/index.html,内容只需改一行 URL:
<script>
window.onload = function() {
const ui = SwaggerUIBundle({
url: "/openapi.json", // 指向你生成的 JSON
dom_id: '#swagger-ui',
});
};
</script>然后访问 http://your-domain.com/swagger/ 即可。别漏掉这步——光有 JSON,没有 UI,就不算“漂亮文档”。
容易被忽略的关键点:
-
openapi.json文件权限必须是 Web 服务器可读(常见坑:生成时用 root,Nginx 无法读取) - 如果用了子目录部署(如
http://a.com/api/),url和注解里的path都得带前缀,否则请求会发到根路径 - 生产环境建议关闭 JSON 文件的直接访问,只通过 Swagger UI 加载,避免暴露接口细节


















