ThinkPHP 6 的 @param 注解在 Swagger UI 中不显示,因其原生不解析 PHPDoc,需配合 zircote/swagger-php 等工具及 @OA\Get 等 OpenAPI v3 标签显式声明;apidoc 则需配置支持 .php 扩展并使用其专用语法,且所有路径、参数、请求体均须手动同步注解与实际路由逻辑。

ThinkPHP 6 的 @param 注解为什么在 Swagger UI 里不显示
因为 ThinkPHP 原生不解析 PHPDoc 注解,@param、@return 这类注释只是注释,不是可执行元数据。Swagger(如 Swagger UI 或 OpenAPI 生成器)需要结构化描述,而 TP6 默认路由和控制器方法不自动提取这些信息。
常见错误现象:swagger.json 里参数全为空、parameters 字段缺失、UI 中显示 “No parameters”;你写了 @param string $id 用户ID,但没任何效果。
- 必须用支持 PHPDoc 解析的工具链,比如
zircote/swagger-php(官方推荐),它通过静态分析读取注释并生成 OpenAPI spec - ThinkPHP 6 的控制器方法需显式加
@OA\Get/@OA\Post等 OpenAPI v3 标签,不能只靠@param -
@param必须写在@OA\Get等标签块内部,且类型要符合 OpenAPI 规范(如string、integer,而非\think\Request)
/**
* @OA\Get(
* path="/user/{id}",
* @OA\Parameter(
* name="id",
* in="path",
* required=true,
* @OA\Schema(type="integer")
* ),
* @OA\Response(response="200", description="OK")
* )
*/
public function read($id) { ... }
用 apidoc 时 /** */ 注释被忽略或报错
apidoc 是基于 JavaScript 的文档生成器,它只识别特定语法格式(类似 JSDoc),对 PHP 原生注释支持弱,且默认不扫描 .php 文件 —— 即使你写了标准 PHPDoc,它也大概率跳过。
使用场景:团队已用 apidoc 搭建了旧版文档站,想快速接入 TP6 接口,结果发现 apidoc -i app/ -o doc/ 什么都没生成。
立即学习“PHP免费学习笔记(深入)”;
- 必须在
apidoc.json中显式添加"extension": [".php"],否则直接无视 PHP 文件 - apidoc 不认
@OA\*,只认自己的语法,例如@apiParam {string} username,写@param string $username没用 - TP6 的依赖注入参数(如
Request $request)不会被自动推导,必须手动写@apiParam,否则字段丢失 - 中文注释需确保文件保存为 UTF-8 无 BOM,否则 apidoc 解析会中断并静默失败
自动生成后接口路径和实际路由不一致
ThinkPHP 的路由可能经过分组、中间件重写、资源路由(Route::resource())或闭包绑定,而 Swagger/OpenAPI 工具只看控制器方法签名和注解,无法感知运行时路由逻辑。
典型表现:swagger.json 里路径是 /index/user/read,但真实访问地址是 /api/v1/users/{id};或者 POST 接口在文档中显示为 GET。
- 不要依赖方法名推导路径,始终在
@OA\Get等标签中手写path=,和route:list输出完全一致 - 若用资源路由,别指望工具自动展开
index/store对应的GET /users、POST /users—— 必须每个动作单独加 OpenAPI 注解 - 带域名或子目录部署时(如
https://api.example.com/v2),需在@OpenApi根标签中配置servers,否则 UI 请求发到 localhost
生成的文档缺少请求体(RequestBody)或校验规则
ThinkPHP 常用 $request->post() 或验证器(Validate 类),但这些逻辑不会反映在 OpenAPI 文档中 —— 注解不写,就等于不存在。
性能影响:漏掉 RequestBody 导致前端无法自动生成请求模板,手动拼 JSON 易出错;缺校验规则会让测试人员误以为字段可空/可乱填。
- POST/PUT 接口必须用
@OA\RequestBody显式定义,嵌套结构用@OA\JsonContent+@OA\Property - 验证器里的
rule = ['name'=>'require|max:25']不会自动转成required: true和maxLength: 25,得人工映射 - 数组字段(如
tags[])要写@OA\Items(type="string"),否则默认当字符串处理 - 上传文件接口需同时写
@OA\RequestBody和@OA\MediaType,并设encoding,不然 Swagger UI 不显示文件选择框
实际跑通的关键不在“怎么配”,而在接受一个事实:TP6 不提供开箱即用的文档生成,所有注解都是单向手工同步。最易被忽略的是路径一致性 —— 开发者改了路由但忘了更新 @OA\Get(path="..."),文档就立刻失效,而且毫无提示。



















