Yii2接口文档不能依赖注释自动生成,因路由映射、隐式行为、格式协商等机制与Swagger解耦;应采用Markdown+真实cURL示例的硬对齐方式,覆盖请求、响应、错误及版本/格式细节。

Yii 框架本身不生成接口文档,yii
estActiveController 提供的是 RESTful 行为骨架,但文档需额外集成或手动维护。强行依赖注释自动生成(如 Swagger)在 Yii2 中容易失效,尤其遇到动作重写、参数绑定或 beforeAction 干预时。
为什么 @api 注释 + Swagger 工具链在 Yii2 里常失效
Yii2 的路由解析和动作执行机制与 Laravel/Symfony 不同:yii
estUrlRule 会把 GET /books 映射到 actionIndex(),但 Swagger-php 默认扫描的是方法签名而非 URL 规则;一旦你重写了 actions() 或禁用了某个标准动作(比如去掉 delete),注释就完全脱钩。
- Swagger-php 只读取 PHPDoc,不感知
urlManager配置里的['class' => 'yii estUrlRule']动态映射逻辑 -
OPTIONS和HEAD响应由yii estController自动处理,但注释无法体现这些隐式行为 - 如果用了
ContentNegotiator或自定义ResponseFormatter,返回结构(如统一包壳{ "data": ..., "code": 0 })不会被注释自动反映
yii
estActiveController 默认动作的请求/响应契约必须手写对齐
哪怕你一个注释都不加,Yii2 仍会按约定行为响应。但前端或测试方需要明确知道:哪些字段必填、分页怎么传、错误码怎么定义。这些不能靠猜。
-
GET /books→ 默认支持page、per-page参数,但per-page上限由yiidataPagination::defaultPageSize控制,不是硬编码在接口里 -
POST /books→ 请求体必须是 JSON,且 Content-Type 必须为application/json;若用表单提交会直接 400,因为RequestParser没配 form-data 支持 -
PUT /books/1→ 只更新提交字段,未提交字段保持原值(ActiveRecord 默认行为),不是 PATCH 语义 - 所有失败响应默认是
text/plain或application/json(取决于ContentNegotiator),但错误结构固定为{"name":"Not Found","message":"Book not found.","code":0,"status":404,"type":"yii\web\NotFoundHttpException"}
最简可行的文档落地方式:用 Markdown + 实际 cURL 示例硬对齐
比折腾注释解析更可靠的是,在 controllers/BookController.php 同级建 docs/books.md,每段对应一个动作,内容只包含三块:真实请求命令、预期响应状态码、关键响应字段说明。
### GET /books ```bash curl -i http://localhost/books?per-page=2&page=1 ``` → 200 OK - `items`: 当前页数据数组,每个对象含 `id`, `name`, `num` - `_meta`: 分页元信息,含 `totalCount`, `pageCount`, `currentPage`, `perPage`
- 避免写“支持过滤”,直接写
GET /books?name=toefl是否生效(默认不生效,除非你重写了search()或findModel()) - 把
Authorization: Bearer xxx放进示例,而不是只写“需鉴权”——Bearer 字段名、token 位置、过期逻辑都影响调用方实现 - 错误示例也要列:比如
POST /books提交空name,响应是 422,body 里name字段带"Name cannot be blank."校验消息
复杂点在于版本控制和多格式响应的文档覆盖
Yii2 的 urlManager 不原生支持路径版本号(如 /v1/books),得靠规则前缀或子域名;而 Accept: application/xml 这类格式协商,实际是否启用取决于 Response::formatters 配置,文档里不写清楚,调用方就会卡在 406。
- 若启用了 XML 输出,
GET /books返回的是<response><items>...</items><_meta>...</_meta></response>,但字段名大小写、是否带命名空间全由XmlResponseFormatter的itemTag、collectionTag决定 - 版本路由如
['pattern' => 'v1/books', 'route' => 'book/index']必须在文档中显式声明,否则 OpenAPI 工具根本识别不出这是 v1 - 所有文档字段描述,必须以实际数据库字段为准——比如
num是 tinyint,就不能写“支持小数”


















