Composer 不支持同一包多主版本共存,因其依赖解析器仅允许一个包名对应一个安装版本;可行方案是目录隔离+版本约束,如将v1/v2 SDK分置不同命名空间并用单一宽松约束控制安装。

直接用 Composer 管理多版本 API 库本身不可行——它不支持同一包多个主版本共存,但你可以绕过限制,靠目录结构 + 版本约束 + 环境隔离实现平滑升级。
为什么不能直接 composer require api/v1 和 api/v2?
Composer 的依赖解析器只认一个包名(如 vendor/api-sdk),无论你写 "vendor/api-sdk": "^1.0" 还是 "vendor/api-sdk": "^2.0",它最终只会装一个版本进 vendor/。试图用两个不同主版本约束强行 require,会触发冲突报错:Root package requires vendor/api-sdk ^1.0 and ^2.0, but these are not compatible.
这不是 bug,是设计使然:Composer 的目标是构建一棵确定、可复现的依赖树,不是运行时动态加载。
- 别在
composer.json里写两行同名包的 require —— 语法合法但求解失败 - 别指望
composer install --ignore-platform-reqs能绕过版本冲突 —— 它跳过 PHP 扩展检查,不跳过依赖逻辑冲突 - 临时 fork 出
vendor/api-sdk-v1和vendor/api-sdk-v2是可行的,但维护成本高、无法享受上游更新
用目录隔离 + 版本约束做灰度切换
真正落地的做法是:把不同版本的 SDK 放进项目内不同命名空间目录,用 Composer 控制哪个版本被实际安装和加载。
例如,你有 v1 和 v2 两个 API SDK,结构如下:
app/Api/
├── V1/
│ └── Client.php // 使用 vendor/api-sdk:^1.5
└── V2/
└── Client.php // 使用 vendor/api-sdk:^2.3
然后在 composer.json 中只声明一个宽松约束:"vendor/api-sdk": ">=1.5.0 ,再靠 CI 或环境变量决定加载哪个子目录。
- 灰度环境 CI 可跑
composer update vendor/api-sdk --with-dependencies并部署app/Api/V2/相关代码 - 生产环境仍用
app/Api/V1/,但 lock 文件已锁定vendor/api-sdk在 1.x 最新版(如 1.9.2) - 关键点:所有环境都提交
composer.lock,但灰度分支的 lock 文件允许包含 2.x 版本
如何让 v1 和 v2 共存且不互相污染?
核心是切断自动加载路径耦合。默认 Composer 会把 vendor/ 下所有包统一注册到 PSR-4 autoloader,但你可以手动排除或重定向。
在 composer.json 的 autoload 段里明确指定:
"autoload": {
"psr-4": {
"App\Api\V1\": "app/Api/V1/",
"App\Api\V2\": "app/Api/V2/"
}
}
同时确保 vendor/api-sdk 的 autoloader 不被全局启用(可通过其 composer.json 的 autoload 字段确认,或用 composer dump-autoload --no-dev 验证)。
- 不要在
AppApiV1Client里use VendorApiSdk*—— 这会让 v1 代码依赖 v2 的类定义 - 每个版本目录应封装完整调用链:HTTP client、DTO、异常处理全部私有化,对外只暴露自己的
Client::call() - 升级时先改
AppApiV2Client,跑通单元测试,再切路由或配置开关,而不是等composer update完才动代码
升级后怎么验证没漏掉 BC break?
API SDK 升级最危险的不是 HTTP 报错,而是静默行为变更:比如 v2 默认开启 gzip 压缩导致老服务返回乱码,或 v2 把 timeout 参数从秒改为毫秒。
必须做的三件事:
- 查该 SDK 的
UPGRADE.md或 release note,重点看 “Changed defaults” 和 “Deprecated options” - 用
composer show vendor/api-sdk看当前装的版本,再跑composer show -a vendor/api-sdk对比可用版本的 require 列表,确认没拉低其他包(如guzzlehttp/guzzle被升到 8.x) - 在 v2 目录下加一个
TestCompatibility.php,手动构造旧请求参数传给新 client,断言响应结构一致 —— 别只测成功,要测400、401、500的错误格式是否兼容
真正容易被忽略的,是 SDK 内部对 php.ini 设置(如 max_execution_time)或扩展(如 ext-curl 版本)的隐式依赖 —— 这些不会出现在 composer.json 的 require 里,但会影响行为。升级前得在目标环境上实测,不能只信本地开发机。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











