CHANGELOG.md 是给人看的,不是给 Composer 解析的;Composer 完全不读取、不校验、不依赖它,只认 composer.json 的 version 字段或 Git tag。

CHANGELOG.md 是给人看的,不是给 Composer 解析的
Composer 完全不读取、不校验、不依赖 CHANGELOG.md。它只认 composer.json 里的 version 字段,或 Git tag(如 v2.1.0)。你写得再详细,composer update 也不会去翻它一眼。
常见错误现象:composer update 后新功能没生效,第一反应是“我是不是漏看了 CHANGELOG”,结果发现 CHANGELOG 根本没提这次修复——因为维护者忘了同步更新,或者写了模糊描述如「优化日志输出」,根本看不出是否影响你的用法。
- CHANGELOG 的唯一真实用途:帮人快速判断「这个版本值不值得升」「我遇到的 bug 是否已修复」
- 必须和 Git tag 严格对齐:每个
v2.1.0发布,对应 CHANGELOG 中一个## [2.1.0] - 2026-08-15段落 - 禁止模糊表述:不要写「提升稳定性」,要写「
HttpClient::send()默认超时从 30s 降为 10s」 - 格式别自创:直接用 Keep a Changelog 规范,Laravel、Symfony、Monolog 全都这么写,工具链也认它
^ 和 ~ 不是松紧程度不同,是锚点坐标系不同
^1.2.3 和 ~1.2.3 看似都“允许小升级”,但它们锁定的不是同一个位置:^ 锚定主版本号(MAJOR),~ 锚定你写到的最左侧非零段(即你明确写出的最后一位数字所在层级)。
所以:^1.2.3 等价于 >=1.2.3 <2.0.0,会升到 1.12.0;~1.2.3 等价于 >=1.2.3 <1.3.0,卡死在 1.2.x。
- 常见误判:
~1.2不是 >=1.2.0 的宽泛匹配,而是隐式等价于~1.2.0,意味着次版本(MINOR)被锁死为 2 - 陷阱场景:某包在
1.8.0废弃了Foo::bar(),但你写的是^1.2.3,composer update仍会拉1.8.0—— 因为它只比对字符串,不分析实际代码变更 - 0.x 包要特别小心:
^0.8.2和~0.8.2表面行为一致(都只允许升到0.8.x),但逻辑完全不同;^0.0.3实际锁死为0.0.3,而~0.0.3却允许升到0.0.999
composer update --root-reqs 不是“部分更新”,是跳过子依赖图重算
composer update --root-reqs 的本质是:只重新解析 composer.json 中你亲手写的那些包(即顶层 require 和 require-dev 条目),完全跳过对它们子依赖的递归检查与重选。
典型坑点:你升级 laravel/framework 到 v11,期望 monolog/monolog 也跟着升,结果它还是 2.x —— 因为 monolog 是 Laravel 的子依赖,--root-reqs 根本不看它。
- 适用场景:你想升级主框架,但不想让底层组件(如
symfony/http-foundation)意外升到不兼容大版本 - 性能优势:省掉整棵依赖树的解析和冲突检测,在大型项目中快很多
- lock 文件变化有限:只改根依赖及其「为满足新约束所必需的最小集」子依赖;比如新 Laravel 要求
symfony/console ^7.0,这个就会动;但psr/log如果旧版仍满足,就原地不动 - 想确认影响范围?先跑
composer why vendor/package或composer depends vendor/package,再决定要不要加--root-reqs
PHP 版本切换不是 composer 自己的事,是调用它的 php 解释器的事
Composer 本身没有“PHP 版本”概念。它只是一个 PHP 脚本,运行时完全取决于启动它的那个 php 命令。混淆这点,90% 的报错就来了。
常见坑:php -v 显示 8.2,但 composer install 报 Attribute 不支持 —— 因为 which composer 返回的是个 shell 脚本,第二行硬编码了 /usr/bin/php74。
- 验证方式必须两步走:
php -v看解释器版本,which composer看执行入口,再打开脚本确认里面调用的 php 路径 - 临时指定 PHP 版本最稳写法:
/usr/bin/php8.2 /usr/local/bin/composer install(Linux/macOS)或C:\php82\php.exe C:\composer\composer.phar update(Windows) - 别靠
export PATH或 alias 长期绑定:不同项目可能要求 PHP 8.1 和 8.2 并存,硬绑定反而增加冲突风险 -
composer self-update --version X.Y.Z只更新 Composer 工具自身,不影响 PHP 版本;若提示 Permission denied,说明 composer 在系统目录,需加sudo或管理员权限
最常被忽略的一点:CHANGELOG 写得再规范,也替代不了实际测试。版本约束再严谨,也拦不住语义化版本之外的 BC break。上线前,务必在对应 PHP 版本下跑一遍关键路径,而不是只信 tag、CHANGELOG 或符号。


















