必须用 composer require zircote/swagger-php 安装,它是唯一支持 PHP 8+ 属性注解(#[OA\Get])的官方维护版本;旧版 @SWG 不兼容 PHP 8.2+,全局安装易冲突,应项目内安装并使用 ./vendor/bin/openapi 命令生成文档。
直接结论:用安装,别碰全局安装或老版本。
它是当前 PHP 8+ 环境下唯一能正确解析属性注解(
)的官方维护版本;旧版
(无命名空间、用
)已彻底不兼容 PHP 8.2+ 的类型系统和属性语法。
为什么必须用
而不是其他名字?
很多人搜“swagger php
composer
”会误装
或过时的 fork,结果运行报错:
或直接跳过注解——因为那些包没迁移到 PHP 8 属性支持,也不再更新。官方唯一认可的包就是
,从 v4.8 开始全面支持
属性写法,且与 Laravel/Slim/Yii2 等框架路由逻辑解耦干净。
安装命令只有一条:
全局安装风险高:
会导致多项目版本冲突,且
命令可能找不到 autoload —— 推荐始终项目内安装
PHP 8.2+ 用户可加一个增强包提升类型推断:
,它能让
自动读取 PHP 类型声明(如
→
),省掉一半手写
命令怎么调?路径和输出格式别写错
装完后,生成命令不是
(那是 Node.js 版),也不是
(v2/v3 遗留路径),而是统一的:
。这个二进制脚本由 Composer 自动生成,自动加载项目 autoloader,确保能识别你代码里的类和命名空间。
基础用法:
—— 扫描
目录下所有 PHP 文件,输出 OpenAPI 3.0 YAML
要输出 JSON?加
:
如果项目有常量定义(如
),需提前加载:
常见错误:
→ 检查是否用了
安装 Composer,或权限问题;用
确认文件存在且可执行
注解写在哪?空行、位置、命名空间一个都不能错
Swagger-PHP 不是“扫描函数签名”,它只认 PHPDoc 块里的
注解,而且对格式极其敏感:注解必须紧贴目标元素(类/方法/参数)上方,中间不能有任何空行,否则整个块被忽略。
Composer 2.9.6
Composer 2.9.6 是 PHP 生态中高效、稳定的依赖管理工具。此版本在性能与兼容性上进一步优化,改进了依赖解析算法,提升大型项目中的安装与更新速度。它支持并行下载任务,显著减少等待时间,并增强了与私有仓库及镜像源的交互稳定性。同时修复了多项命令行交互与内存使用相关的缺陷,确保在复杂依赖关系下依然可靠运行。无论是新项目初始化还是现有系统维护,Composer 2.9.6 都能为开发者提供流畅、精准的依赖管理体验。
下载
正确写法(无空行):
错误写法(空行导致失效):
必须 use 别名:
,否则
会被当成普通文本,不解析
参数名必须和实际接收一致:比如
,但控制器里是
→ 文档和真实请求就对不上,前端调试必 404
Body 提交必须显式写
+
,光写
不会出现在请求体结构里
生成的文档为啥点 “Try it out” 就 404?
因为默认生成的
里没有
字段,Swagger UI 不知道该往哪个域名+端口发请求。这不是后端没跑起来,是文档缺配置。
补上服务器地址最简单:
开发环境可配多个:
和
如果不写
,Swagger UI 默认用当前页面 URL 的 origin(比如
)拼路径,显然不对
另一个隐形坑:
和真实路由前缀(如
)不一致 → 文档路径和接口实际路径错位,前端照着文档调就 404
最容易被忽略的是:Swagger-PHP 不读取任何框架路由配置,它只认你写的
字符串。所以哪怕你用 Laravel 的
,也得手动在注解里写成
—— 这个映射必须人工对齐,自动化靠不住。
composer require zircote/swagger-php#[OA\Get]swagger-php@SWGzircote/swagger-phpswagger-api/swagger-phpAttribute "OA\Get" does not existzircote/swagger-php#[OA\*]composer require zircote/swagger-phpcomposer global require zircote/swagger-phpopenapicomposer require radebatz/type-info-extras@OA\Propertystring $nametype="string"openapiswaggerphp ./vendor/zircote/.../bin/swagger./vendor/bin/openapi./vendor/bin/openapi src/ -o openapi.yamlsrc/--format json./vendor/bin/openapi src/ --format json -o openapi.jsonAPP_ENV./vendor/bin/openapi --bootstrap constants.php src/ -o openapi.yamlCould not open input file: ./vendor/bin/openapi--no-bin-dirls -l ./vendor/bin/@OA\*/** @OA\Get(path="/api/users") */ public function index() { ... }/** @OA\Get(path="/api/users") */
public function index() { ... }
use OpenApi\Annotations as OA;@OA\Get@OA\Parameter(name="page", in="query")$request->getQueryParam('p')@OA\RequestBody@OA\JsonContent@OA\Propertyopenapi.yamlservers/** @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\Serverhttp://localhost/swagger-ui/path="/users"/api/v1/userspathRoute::get('users', ...)path="/api/v1/users"