ThinkPHP需借助第三方工具生成API文档,如think-swagger要求显式路由绑定、扁平化参数注释及@required标记;topthink/think-apidoc用自定义标签;swagger-php支持OpenAPI标准但注释成本高。

ThinkPHP本身不生成API文档,必须靠注释 + 第三方工具解析。别指望写完控制器就自动出 Swagger 页面——那得你手动配对、写对注释、跑对命令才行。
think-swagger 要求路由明确绑定控制器方法
它只扫描 route/app.php 里显式写出的路由所指向的 public 方法。闭包路由、__invoke、中间件里写的逻辑,注释再全也进不了文档。
- ✅ 正确写法:
Route::post('api/user', 'api.UserController/save'); - ❌ 错误写法:
Route::post('api/user', function () { ... });或Route::resource('user', 'UserController');(没加only限定) - 多级命名空间如
api\v2\UserController,要确认think-swagger配置里的paths包含该目录
@param array 不会被解析,必须拆成扁平字段
think-swagger 不识别 @param array $data 这类泛型注释,也不会递归展开数组结构。它只认具体字段名+基础类型。
- ❌
@param array $user→ 文档里直接消失 - ✅
@param string $user_name、@param int $user_age、@param string $user_address_city - 嵌套参数如
user[profile][avatar],就得写成@param string $user_profile_avatar - 必填字段必须加
@required(think-swagger 特有语法,不是标准 PHPDoc)
用 topthink/think-apidoc 更轻量,但注释格式完全不同
这是 ThinkPHP6 官方生态的方案,不依赖 OpenAPI 规范,也不需要 @OA\ 注解,但注释标签是 ThinkPHP 自定义的。
立即学习“PHP免费学习笔记(深入)”;
- 必须用
@ApiTitle、@ApiParams、@ApiReturn等标签,不能混用 PHPDoc 标准 -
@ApiParams要写全:name、type、required、description,例如@ApiParams(name="id", type="integer", required=true, description="用户ID") - 生成命令是
php think apidoc --module api --path ./public/apidoc --type json,路径和模块名必须匹配实际目录结构 - 它不校验注释与验证器是否一致,
validate()里写了id|require,但注释漏了required=true,文档里就不会标必填
swagger-php(zircote)支持 OpenAPI 3.0,但注释成本高
如果你项目已用 Laravel 风格或计划对接外部平台,zircote/swagger-php 是更通用的选择,但它要求写 @OA\Get、@OA\Parameter 这类结构化注解,不是简单 @param 就能搞定。
- 安装:
composer require zircote/swagger-php - 注释必须带命名空间:
use OpenApi\Annotations as OA;,然后在方法上写@OA\Post(...) - 生成命令类似:
php vendor/bin/openapi app/ --output public/doc/openapi.json - 生成的是 JSON/YAML,还得自己把
swagger-ui放到public/swagger-ui/并配置 URL 指向该文件 - 好处是生成结果符合 OpenAPI 标准,可被 Postman、Apifox 等工具直接导入;坏处是注释量大,改个参数要动两处(验证规则 + 注解)
最常被忽略的一点:文档和验证逻辑必须人工对齐。无论用哪种工具,@required 和 validate() 里的 require 不一致,或者 @ApiParams 类型写成 string 但实际接收的是 int,文档就只是个“看起来很美”的摆设。



















