Swagger注解不生效主因是工具链未配对、注释格式错误或扫描路径不准;需装zircote/swagger-php与openapi/openapi,注释紧贴方法、用完整命名空间、path匹配真实路由,生成时指定正确目录并确保UTF-8无BOM,UI须通过HTTP访问且配置@OA\Server。

ThinkPHP 项目里 Swagger 注解不生效,基本不是框架问题,而是工具链没配对、注释没写对、路径没扫到——三者占了 90% 的失败原因。
装对包:zircote/swagger-php + openapi/openapi 缺一不可
很多人卡在第一步:vendor/bin/openapi 命令根本不存在,或者运行后输出空 JSON。这不是 ThinkPHP 限制,是依赖没装全。
- 必须执行
composer require zircote/swagger-php(注意不是swagger-php-dev或旧版swagger-php) - v4+ 版本已剥离注解类,必须额外装
composer require openapi/openapi,否则@OA\Get这类注释会被完全忽略 - 检查
vendor/zircote/swagger-php/src/Annotation.php是否存在;若不存在,说明装的是废弃的 v2 分支 - 别手动
use OpenApiAnnotations as OA—— 扫描器只识别全局命名空间下的@OA\Xxx
注释写法:紧贴 + 完整命名空间 + 路径对齐真实路由
ThinkPHP 的路由前缀(比如 api/)不会被自动注入到文档里,@OA\Get(path="/user") 和实际访问地址 /api/user 不一致,文档就等于废的。
- 注释块必须紧贴方法声明上方,中间不能有空行;例如
/** @OA\Get(...) */ public function index()合法,换行后就失效 - 所有注释必须用完整命名空间:
@OA\Get,不是@Get或@SWGGet(v2 已废弃) -
path值必须和最终对外暴露的 URL 完全一致,包括/api/v1这类前缀;ThinkPHP 的route配置或group中间件不参与自动推导 - 参数不能靠函数签名猜:
function detail($id)不会自动生成id查询参数;必须显式写@OA\Parameter(name="id", in="query", ...) - JSON Body 提交必须用
@OA\RequestBody+@OA\JsonContent描述结构,光写@OA\Property没用
生成命令:指定目录要准,权限和编码不能错
常见现象是命令跑通但 openapi.json 里 paths 为空,或只扫到部分控制器——大概率是扫描路径没覆盖到你的实际代码位置。
立即学习“PHP免费学习笔记(深入)”;
- ThinkPHP5 默认控制器在
app/api/controller/,ThinkPHP6 多为app/controller/,生成时路径必须精确指向这些目录,例如:./vendor/bin/openapi app/controller/ -o public/docs/openapi.json - 确保目标 PHP 文件能被 Composer 自动加载(即在
composer.json的autoload.psr-4或classmap中注册) - Linux/macOS 下注意文件权限:如果控制器文件属主不是当前执行用户,
openapi可能静默跳过 - 文件编码必须是 UTF-8 无 BOM;BOM 会导致注释解析失败,且无报错提示
- 生成后务必打开
openapi.json看一眼是否有"openapi": "3.0.3"和真实"paths",没有就说明扫描失败
接入 Swagger UI:静态托管 + 正确 URL + 必须走 HTTP
很多人双击 index.html 打开 UI,看到 Failed to load spec 就以为是生成失败——其实是浏览器 CORS 策略直接拦截了本地 file 协议读取 JSON。
- 把 Swagger UI 解压到
public/docs/(ThinkPHP 的 Web 根目录下),不要放app/或runtime/里 - 修改
public/docs/index.html中的url字段为"./openapi.json"或绝对路径如"/docs/openapi.json" - 必须通过 Web 服务器访问,例如启动内置服务:
php -S localhost:8000 -t public,然后浏览器打开http://localhost:8000/docs/ - 别漏掉
@OA\Server;没这个字段,UI 的 “Try it out” 功能会默认发请求到/,必然 404。加在@OA\Info里:@OA\Server(url="http://localhost:8000")
最易被忽略的一点:ThinkPHP 的中间件(如鉴权、跨域)不影响文档生成,但会影响 UI 测试时的真实请求结果;文档里的 @OA\Response 必须严格对应你实际返回的 JSON 结构,哪怕只是多一个 data 包裹层,也要在 @OA\JsonContent 里写清楚。



















