必须用 composer require zircote/swagger-php 安装,它是唯一支持 php 8+ 属性注解(#[oa\get])的官方维护版本;旧版 @swg 不兼容 php 8.2+,全局安装易冲突,应项目内安装并使用 ./vendor/bin/openapi 命令生成文档。

直接结论:用 composer require zircote/swagger-php 安装,别碰全局安装或老版本。 它是当前 PHP 8+ 环境下唯一能正确解析属性注解(#[OA\Get])的官方维护版本;旧版 swagger-php(无命名空间、用 @SWG)已彻底不兼容 PHP 8.2+ 的类型系统和属性语法。
为什么必须用 zircote/swagger-php 而不是其他名字?
很多人搜“swagger php composer”会误装 swagger-api/swagger-php 或过时的 fork,结果运行报错:Attribute "OA\Get" does not exist 或直接跳过注解——因为那些包没迁移到 PHP 8 属性支持,也不再更新。官方唯一认可的包就是 zircote/swagger-php,从 v4.8 开始全面支持 #[OA\*] 属性写法,且与 Laravel/Slim/Yii2 等框架路由逻辑解耦干净。
- 安装命令只有一条:
composer require zircote/swagger-php - 全局安装风险高:
composer global require zircote/swagger-php会导致多项目版本冲突,且openapi命令可能找不到 autoload —— 推荐始终项目内安装 - PHP 8.2+ 用户可加一个增强包提升类型推断:
composer require radebatz/type-info-extras,它能让@OA\Property自动读取 PHP 类型声明(如string $name→type="string"),省掉一半手写
openapi 命令怎么调?路径和输出格式别写错
装完后,生成命令不是 swagger(那是 Node.js 版),也不是 php ./vendor/zircote/.../bin/swagger(v2/v3 遗留路径),而是统一的:./vendor/bin/openapi。这个二进制脚本由 Composer 自动生成,自动加载项目 autoloader,确保能识别你代码里的类和命名空间。
- 基础用法:
./vendor/bin/openapi src/ -o openapi.yaml—— 扫描src/目录下所有 PHP 文件,输出 OpenAPI 3.0 YAML - 要输出 JSON?加
--format json:./vendor/bin/openapi src/ --format json -o openapi.json - 如果项目有常量定义(如
APP_ENV),需提前加载:./vendor/bin/openapi --bootstrap constants.php src/ -o openapi.yaml - 常见错误:
Could not open input file: ./vendor/bin/openapi→ 检查是否用了--no-bin-dir安装 Composer,或权限问题;用ls -l ./vendor/bin/确认文件存在且可执行
注解写在哪?空行、位置、命名空间一个都不能错
Swagger-PHP 不是“扫描函数签名”,它只认 PHPDoc 块里的 @OA\* 注解,而且对格式极其敏感:注解必须紧贴目标元素(类/方法/参数)上方,中间不能有任何空行,否则整个块被忽略。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 正确写法(无空行):
/** @OA\Get(path="/api/users") */ public function index() { ... } - 错误写法(空行导致失效):
/** @OA\Get(path="/api/users") */ <p>public function index() { ... }</p> - 必须 use 别名:
use OpenApi\Annotations as OA;,否则@OA\Get会被当成普通文本,不解析 - 参数名必须和实际接收一致:比如
@OA\Parameter(name="page", in="query"),但控制器里是$request->getQueryParam('p')→ 文档和真实请求就对不上,前端调试必 404 - Body 提交必须显式写
@OA\RequestBody+@OA\JsonContent,光写@OA\Property不会出现在请求体结构里
生成的文档为啥点 “Try it out” 就 404?
因为默认生成的 openapi.yaml 里没有 servers 字段,Swagger UI 不知道该往哪个域名+端口发请求。这不是后端没跑起来,是文档缺配置。
- 补上服务器地址最简单:
/** @OA\Info(title="My API", version="1.0") @OA\Server(url="https://api.example.com/v1") */
- 开发环境可配多个:
@OA\Server(url="http://localhost:8000/api")和@OA\Server(url="https://staging.example.com/api") - 如果不写
@OA\Server,Swagger UI 默认用当前页面 URL 的 origin(比如http://localhost/swagger-ui/)拼路径,显然不对 - 另一个隐形坑:
path="/users"和真实路由前缀(如/api/v1/users)不一致 → 文档路径和接口实际路径错位,前端照着文档调就 404
最容易被忽略的是:Swagger-PHP 不读取任何框架路由配置,它只认你写的 path 字符串。所以哪怕你用 Laravel 的 Route::get('users', ...),也得手动在注解里写成 path="/api/v1/users" —— 这个映射必须人工对齐,自动化靠不住。










