写"2.0.0"锁死精确版本,update不升级;"^2.0"允许>=2.0.0且

composer.json里写"2.0.0"和"^2.0"到底差在哪
写"monolog/monolog": "2.0.0"是锁死到精确版本,后续composer update不会动它,连安全补丁都拿不到;写"monolog/monolog": "^2.0"才表示允许装2.0.0到3.0.0之间的所有向后兼容版本。
常见错误现象:本地开发用"^2.0"装了2.8.0,上线 CI 跑composer install却装出2.9.0——不是约束失效,而是composer.lock没提交进 Git,导致 CI 重新解析最新匹配版本。
-
^2.0等价于>=2.0.0 ,推荐用于主版本已稳定的包 -
~2.1等价于>=2.1.0 ,适合想严格控小版本的场景(比如支付 SDK) -
2.*不推荐:它不遵循 SemVer,可能意外引入破坏性变更 -
dev-main禁用于生产:每次update都拉最新提交,无法被composer.lock锁定
为什么composer update会升级我没碰过的包
因为composer update不带参数时,默认更新所有满足约束的包,哪怕你只改了一行composer.json里的注释。
真正危险的是你以为“只改了 A 包”,但 B 包的依赖约束是^1.0,而它在composer.lock里存的是1.2.3,这次 update 就可能把它升到1.9.0——这不是 bug,是约束生效的正常表现。
- 只更新指定包:
composer update monolog/monolog - 避免连带升级子依赖:别加
--with-dependencies,除非你明确需要 - 想最小化变更:
composer update --minimal-changes(Composer 2.2+) - CI/CD 中永远用
composer install,靠composer.lock还原,而非update
conflict字段不是摆设,是救命稻草
当composer install在 CI 上装出和本地不同的psr/log版本,或某天突然报Class not found,大概率是间接依赖被上游包带偏了。这时在require里写死没用,得靠conflict。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
例如,你确认项目无法兼容guzzlehttp/guzzle的 8.x 版本,就在composer.json根级加:
"conflict": {
"guzzlehttp/guzzle": ">=8.0.0"
}
Composer 解析时会直接拒绝任何匹配的版本,连尝试安装都不会发生。
-
conflict不修改已安装包,只影响下一次install或update - 提示里出现
because package-a requires guzzlehttp/guzzle ^7.5 and package-b requires ^8.0,就是该加conflict的信号 - 别用
require-dev“假装需要”某个版本来锁间接依赖——会污染 autoloader
私有包打 tag 和composer.json怎么配才不翻车
私有包的版本发布必须靠 Git tag,Satis 或 Packagist 都只认v2.1.0这种格式的 tag;如果没打 tag,dev-main这类分支引用才有效,但它绕过所有版本约束。
常见错误:在私有包自己的composer.json里写"version": "2.1.0"——这个字段会被 Composer 忽略,完全无效。
- Git tag 必须带
v前缀:git tag v2.1.0 -m "release",再git push --tags - 私有包
composer.json中只需正确声明name和require,不用写version - 若团队尚未严格执行 SemVer,建议统一用
~2.1.3或精确版本2.1.3,而非^2.1 - 禁止在业务项目
require中直接引用dev-main;如需测试快照,应建dev分支并用"mycompany/sdk": "dev-dev as 2.1.3"显式别名
composer.lock里记录的version和source.reference。删掉 lock 文件再 install,就等于放弃所有版本控制。










