composer 不处理 psr 接口升级,仅按 composer.json 加载指定版本的 psr 包;psr 接口变更需人工验证兼容性,依赖更新后须检查类型签名、运行时行为及实现包适配情况。

Composer 本身不处理 PSR 接口升级——它根本不关心你用的是 PSR-7、PSR-14 还是 PSR-18。它只管加载类,不管接口怎么变。
PSR 接口升级和 Composer 没有直接关系
PSR 是 PHP-FIG 制定的接口规范,比如 Psr\Http\Message\RequestInterface 或 Psr\EventDispatcher\EventDispatcherInterface 。这些接口定义在各自独立的包里(如 psr/http-message 、 psr/event-dispatcher ),它们的版本升级由对应包的 maintainer 控制,Composer 只负责按 composer.json 中的 require 声明去拉取指定版本。
常见误解是:「我升级了 PSR 包,我的代码就自动适配新接口了」。事实是:
- 升级
psr/http-message:^2.0后,RequestInterface::getUri()返回类型从UriInterface变为?UriInterface(可空),你的代码若没加空值检查,运行时可能出 Notice 或 Fatal -
psr/log:^3.0移除了Psr\Log\LogLevel常量类,改用原生const定义,直接use Psr\Log\LogLevel会报错 - PSR 接口包本身不含实现,只是契约;你项目中真正调用的类(比如
Nyholm\Psr7\Request)是否兼容新 PSR 版本,得看那个实现包有没有同步更新
如何安全升级 PSR 接口依赖
关键不是“怎么让 Composer 升级”,而是“怎么验证升级后仍能工作”。步骤如下:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 先查目标 PSR 包的 CHANGELOG(例如 psr/http-message CHANGELOG),确认破坏性变更点
- 在
composer.json中显式声明要升级的 PSR 包,比如:"psr/http-message": "^2.0",避免被其他依赖间接拖入不兼容版本 - 运行
composer update psr/http-message --with-dependencies,强制连带更新所有依赖它的包(如guzzlehttp/psr7) - 重点检查:所有
instanceof判断、@param类型注解、mock 对象构造是否仍匹配新接口签名 - 如果项目用了静态分析工具(如 PHPStan),把 level 调到 8+,它会在编译期捕获多数接口不匹配问题
为什么 composer dump-autoload 不解决 PSR 接口问题
composer dump-autoload 只刷新类文件路径映射,和接口无关。即使你把 psr/log 升到 v3,但代码里还写 use Psr\Log\LogLevel; LogLevel::ERROR , dump-autoload 不会报错,PHP 运行时才会抛 Class 'Psr\Log\LogLevel' not found 。
真正起作用的是:
-
composer validate:只能校验composer.json格式,不检查 PSR 兼容性 -
composer check-platform-reqs:只检查 PHP 版本和扩展,不检查接口契约 - 必须靠人工比对 + 类型检查工具 + 运行时测试覆盖
多 PSR 版本共存时的陷阱
某些项目会同时引入 psr/container:^1.0 和 psr/container:^2.0 (比如通过不同依赖间接引入),Composer 默认允许这种“版本分裂”,但会导致:
- 同一个接口名(如
Psr\Container\ContainerInterface)在内存中存在两份定义,instanceof判断可能意外失败 - PHPStan 或 Psalm 报告 “Cannot resolve type” 类错误
- 解决方法只有两个:
composer prohibit-conflicts插件强制排他,或手动统一降级/升级到同一主版本
最常被忽略的一点:PSR 接口包的语义化版本号(如 ^1.0 )只约束其自身发布节奏,不约束其实现包是否同步适配——你得自己盯紧 nyholm/psr7 、 laminas/diactoros 等实现库的更新日志。










