Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
18b4696
update massage
tw2066 Aug 26, 2025
b5368ac
update massage
tw2066 Oct 7, 2025
cfa756c
update README.md
tw2066 Dec 15, 2025
6cf3ed8
增加注释说明
tw2066 Feb 5, 2026
723c49a
Scalar 支持多个url
tw2066 Feb 5, 2026
bc17a0f
支持json数组
tw2066 Feb 11, 2026
fe825d8
Merge pull request #41 from tw2066/json_array
tw2066 Feb 11, 2026
c6e11f2
优化获取全局操作ID-route
tw2066 Feb 11, 2026
ef386ea
修复isRequestBody null
tw2066 Feb 11, 2026
73fed96
composer update
tw2066 Feb 25, 2026
4fb9021
Merge remote-tracking branch 'origin/master'
tw2066 Feb 25, 2026
97d2562
Adaptation PHP-Parser v5
tw2066 Feb 26, 2026
87f6c65
更新swagger资源5.32
tw2066 Feb 28, 2026
298593e
add test
tw2066 Mar 26, 2026
0e7e118
Optimize the code
tw2066 Mar 26, 2026
8f4abb9
update SWOOLE_VERSION
tw2066 Mar 26, 2026
a4f9c90
update SWOOLE_VERSION
tw2066 Mar 26, 2026
d68486d
update composer.json
tw2066 Mar 26, 2026
bc2bd69
update test
tw2066 Mar 26, 2026
69295c7
update test
tw2066 Mar 27, 2026
8aa93c4
update test
tw2066 Mar 27, 2026
32b408b
test
tw2066 Mar 27, 2026
be025e7
test
tw2066 Mar 27, 2026
3dfb3ae
test
tw2066 Mar 27, 2026
f9e9fe6
test
tw2066 Mar 27, 2026
130c31e
withHeader charset=utf-8
tw2066 Mar 30, 2026
f8437dc
optimized code
tw2066 Mar 30, 2026
affae80
支持ai读取llms.txt
tw2066 Mar 31, 2026
96ddbff
Repair SwaggerPathsTest
tw2066 Mar 31, 2026
7f5f32a
Repair testGetPrefixUrlFallsBackToDefault
tw2066 Mar 31, 2026
f823230
update LLM description
tw2066 Apr 1, 2026
d42cc00
chore(deps): 更新 PHP 版本要求并移除测试矩阵中的 Hyperf 版本
tw2066 Jun 9, 2026
f40c708
chore(ci): 移除旧的 CI 配置并保留新的 ci32 工作流
tw2066 Jun 9, 2026
e03c689
chore(deps): 更新 phpstan 依赖版本
tw2066 Jun 16, 2026
830ed6f
fix(security): 解决Swagger文件路径
tw2066 Jun 18, 2026
9876456
docs(api): 添加 CLAUDE.md 开发指南并完善文档
tw2066 Jul 23, 2026
ee8e457
chore(ci): 更新 composer 命令参数以优化依赖管理
tw2066 Jul 23, 2026
ce526e7
chore(deps): 更新依赖安装命令参数
tw2066 Jul 23, 2026
c7969c1
fix(swagger): 修复路由路径占位符匹配正则表达式
tw2066 Jul 23, 2026
d492913
Merge pull request #44 from tw2066/k3
tw2066 Jul 23, 2026
774c720
refactor(Swagger): 优化路由路径参数判断逻辑
tw2066 Jul 24, 2026
ea78544
refactor(config): 简化 PHPUnit 配置文件
tw2066 Aug 12, 2026
48905bd
Merge remote-tracking branch 'origin/master'
tw2066 Aug 12, 2026
6438106
refactor(Swagger): 调整API文档路径信息存储方式
tw2066 Aug 18, 2026
1bf0fe8
fix(swagger): 将Swagger禁用日志级别从info调整为debug
tw2066 Aug 26, 2026
88fd506
refactor(Swagger): 简化类方法路径获取逻辑
tw2066 Sep 1, 2026
1e13afb
test(api-docs): 更新Swagger路径测试以验证完整方法路径
tw2066 Sep 3, 2026
574c924
Merge branch 'master' into 3.1-up
tw2066 Sep 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## 项目概述

`tangwei/apidocs` — 基于 Hyperf 的 Swagger/OpenAPI 3.x 文档自动生成组件。通过 PHP 8 Attributes 扫描控制器路由,在应用启动时生成 OpenAPI 描述文件,并内置多种文档 UI(Swagger UI、Knife4j、Redoc、RapiDoc、Scalar)及 llms.txt 输出。支持 Swoole / Swow / phar 部署。

## 常用命令

```bash
composer test # 运行全部测试(phpunit -c phpunit.xml)
vendor/bin/phpunit -c phpunit.xml --filter testMethodName tests/SwaggerPathsTest.php # 运行单个测试
composer analyse # PHPStan 静态分析(-l 0,仅 src/)
composer cs-fix # php-cs-fixer 格式化 src 和 tests
```

CI 矩阵为 PHP 8.2/8.3/8.4 + Hyperf 3.2(pin `hyperf/di:3.2.*` + `tangwei/dto:dev-master`)。本包通过 `tangwei/dto ~3.2` 传递依赖 Hyperf ~3.2,不兼容 Hyperf 3.1。

## 架构核心

### 启动期生成流水线(理解本组件的关键)

OpenAPI 文件**不是请求时生成的**,而是在应用启动时由事件监听器驱动:

1. `BootAppRouteListener`(BootApplication 事件)— 在第一个 HTTP server 的路由上注册 `{prefix_url}` 路由组(UI 页面、`/webjars/*`、`{httpName}.json/yaml`、llms.txt 等),并把文档访问 URL 写入静态属性供 `AfterWorkerStartListener` 打印。
2. `AfterDtoStartListener`(`Hyperf\DTO\Event\AfterDtoStart` 事件,由 tangwei/dto 在扫描完路由后发出)— **每个 server 触发一次**:遍历该 server 的全部路由 Handler,对每个 `控制器@方法` 调 `SwaggerPaths::addPath()` 解析注解生成 `OA\PathItem`,最后 `SwaggerOpenApi::save()` 写入 `output_dir/{serverName}.json|yaml`。
3. `SwaggerOpenApi` 是**按 server 累积状态**的构建器:`init(serverName)` 重置 → 各 Generate 类向其 SplPriorityQueue(paths/tags 按 position 排序)投递 → `save()` 落盘 → `clean()` 释放。多 server 应用会为每个 server 各生成一份文件。

**注意**:`dtoConfig->isScanCacheable()` 为 true 时 `AfterDtoStartListener` 跳过生成(第 56-58 行提前 return)——扫描缓存模式下运行环境可能没有 output_dir 中的文件。

### 注解 → OpenAPI 的转换链

- `SwaggerPaths::addPath()` 读取类/方法注解(`#[Api]`、`#[ApiOperation]`、`#[ApiHeader]`、`#[ApiResponse]`、`#[ApiFormData]`、`#[ApiSecurity]`),委托给:
- `GenerateParameters` — 从方法签名 + DTO 类生成 parameters/requestBody
- `GenerateResponses` — 从方法**返回类型**(`MethodDefinitionCollector`)+ `#[ApiResponse]` + 全局 `GlobalResponse` 配置生成 responses;控制器方法返回具体类才能获得准确文档
- `SwaggerComponents` — DTO 类的 `#[ApiModelProperty]`/验证注解 → `components.schemas`,继承自 tangwei/dto 的 `PropertyManager`
- `SwaggerConfig` 用 JsonMapper(`bIgnoreVisibility`)把 `config/autoload/api_docs.php` 直接映射到私有属性——**配置键名必须与属性名一致**(snake_case),新增配置项 = 新增同名私有属性。

### ApiVariable 代理类机制

`#[ApiVariable]` 标记的 DTO 属性(类型在运行时才能确定的"可变类型")由 `GenerateProxyClass` 在运行时通过 PHP-Parser 重写原类 AST(`Ast\ResponseVisitor` 替换属性类型和命名空间为 `ApiDocs\Proxy`),写入 `proxy_dir`(默认 `runtime/container/proxy/`)供 schema 生成使用。

### 文件服务端点

`SwaggerController`(json/yaml/md/静态文件)和 `SwaggerUiController`(各 UI 页面 + knife4j webjars)按请求实例化。静态资源路径硬编码指向 `vendor/tangwei/swagger-ui/dist` 和 `vendor/tangwei/knife4j-ui/dist`(knife4j-ui 是 suggest 依赖,未安装时相关路由会 500)。三类端点校验方式不同:`getFile` 用 scandir 白名单精确匹配,`knife4jFile` 用 sanitize + realpath 前缀校验(嵌套路径无法白名单)。`fileResponse` 在 Swoole 下用 `SwooleFileStream`(sendfile),Swow/phar 下退回 `file_get_contents`。

### 与 tangwei/dto 的关系

本组件重度依赖 `tangwei/dto`(`Hyperf\DTO\*`):注解扫描(`ApiAnnotation::classMetadata`)、DTO 验证、属性管理、Mapper 均来自该包。修改扫描/注解相关行为时,先确认逻辑在本包还是 dto 包。

## 测试约定

- 测试基类 `SwaggerUiControllerTestable` 重写了构造函数且**不调 `parent::__construct`**——父类构造函数的逻辑(目录检查、scandir)在测试中不会被覆盖到。
- `tests/Request/` 下的 DTO 是多个测试共用的 fixture。
- CI 在 hyperf/hyperf 容器镜像中运行,本地无 Swoole 也可跑 phpunit(测试不依赖 server 启动)。

## 示例与文档

- `example/` 目录是注解用法的活文档(各参数注解、分页、枚举、递归类型的完整示例),改注解行为时对照它验证。
- README.md / README_EN.md 需保持同步;环境要求以 composer.json 为准(README 中的版本号容易滞后)。
Loading
Loading