ThinkPHP 8.0 接口文档需通过 Swagger-PHP 实现自动同步:安装 zircote/swagger-php,在 public 方法上方用 @OA\* 注解精确声明路径、参数(含 @OA\Parameter 和 @OA\RequestBody)、响应,path 必须与 Route::get() 注册的完整 URL 严格一致,生成 public/swagger.json 并确保可直接 HTTP 访问。

TP8.0 接口文档维护繁琐,每次改接口就得同步更新 Markdown 或 Word 文档,前后端反复确认参数类型和返回结构,耗时又易出错;用 Swagger 注解驱动文档生成,能直接从控制器代码里抽取出路径、参数、响应体,实时保持文档与代码一致。
安装 Swagger-PHP 依赖
执行命令安装核心工具:composer require zircote/swagger-php。
国内网络下若卡在下载阶段,先运行 composer config repo.packagist composer https://packagist.phpcomposer.com 切换镜像源再重试。
装完立刻检查 vendor/zircote/swagger-php 目录是否存在——别只看终端显示 success,目录不存在等于没装上。
在控制器方法上写标准 @OA 注解
注解必须写在 public 方法正上方的 /** */ 块内,且不能空行,否则扫描器完全忽略。
方法签名和注解要严格对应:函数带默认值 public function index($page = 1),注解就必须显式声明 @OA\Parameter(name="page", in="query", required=false),否则文档里不会出现该参数。
Body 提交必须用 @OA\RequestBody 包裹 @OA\JsonContent,光写 @OA\Property 不生效,Swagger-PHP 不会自动推导请求体结构。
示例完整注解:
/*** @OA\Get(* path="/api/v2/users",* summary="获取用户列表(v2)",* tags={"用户管理"},* @OA\Parameter(name="page", in="query", description="页码", required=false, @OA\Schema(type="integer")),* @OA\Response(response=200, description="成功", @OA\JsonContent(@OA\Property(property="data", type="array", @OA\Items(@OA\Schema(ref="#/components/schemas/User")))))*/
确保路由注册路径与注解 path 完全一致
ThinkPHP 的路由配置决定真实访问地址,注解里的 path 必须一字不差匹配它。
比如你写了 Route::get('api/v2/users', [UserController::class, 'index']);,注解就必须是 path="/api/v2/users",少个斜杠、多一级版本号、漏掉前缀都会导致该接口不进文档。
资源路由 Route::resource('users', UserController::class); 默认注册 7 个动作,但 Swagger-PHP 只扫描你实际写了注解的方法——没加注解的 create 或 destroy 不会出现在文档里,这点和 ThinkPHP 路由机制无关,纯静态扫描行为。
生成 openapi.json 并验证可访问性
第一步:进入项目根目录,执行生成命令:php vendor/bin/openapi app/controller/ --output public/swagger.json。
第二步:确认输出路径 public/swagger.json 能被 Web 服务器直接读取——浏览器访问 http://localhost/swagger.json 必须返回合法 JSON,不能是 403、404 或 Nginx 拦截 .json 后缀。
第三步:如果报错 Class 'OpenApi\Annotations\Get' not found,检查控制器顶部是否漏了 use OpenApi\Annotations as OA;,同时确认 PHP 版本 ≥ 8.0(旧版需额外装 doctrine/annotations)。
大项目建议加内存限制避免超时:php -d memory_limit=-1 vendor/bin/openapi app/controller/ -o public/swagger.json。











