^1.2.3允许升级到1.x.x中所有兼容版本(如1.2.4、1.3.0,但不包括2.0.0),最常用且推荐;~1.2.3仅允许补丁级更新,等价于>=1.2.3

composer.json 里怎么写版本通配符
Composer 不支持 Shell 那种 * 通配符,但有自己的一套语义化版本匹配规则。最常用的是 ^ 和 ~,它们不是“通配符”,而是“版本范围前缀”,行为差异很大,选错会导致意外升级或锁死。
-
^1.2.3允许升级到1.x.x中所有兼容版本(即1.2.4、1.3.0,但不包括2.0.0)——这是最常用、也最推荐的写法 -
~1.2.3更保守:只允许补丁级更新,等价于>=1.2.3 ,不会升到 <code>1.3.0 -
1.*看似像通配符,实际等价于>=1.0.0 ,会拉取 <code>1.999.999这类非常激进的版本,风险高,不建议用 -
*(单独一个星号)在 Composer 中是非法写法,会报错Invalid version string "*"
为什么 ^ 比 ~ 更常用
因为大多数 PHP 包遵循 SemVer(语义化版本),^ 能在保持向后兼容的前提下自动获取安全补丁和小功能更新;而 ~ 容易卡在旧主版本里,比如 ~2.1.0 锁死在 2.1.x,错过 2.2.0 的重要改进。
- 用
^前先确认包是否真按 SemVer 发版(看它的CHANGELOG或 GitHub releases) - 如果包维护混乱(比如
1.0.0→1.1.0就破坏接口),那就别信^,改用固定版本如1.0.0或~1.0.0 -
^0.x.y在 0.x 阶段行为特殊:^0.1.0只允许>=0.1.0 ,相当于 <code>~0.1.0—— 这是 SemVer 规定,不是 Composer bug
运行 composer update 时版本没变?检查这几点
常见现象:改了 composer.json 里的版本约束,执行 composer update 后 composer.lock 和已安装包完全没动。这不是缓存问题,而是 Composer 的依赖解析逻辑在起作用。
-
composer.lock优先级高于composer.json:只要 lock 文件里已有满足新约束的版本,就不会重装 - 想强制按新约束重算,得加
--with-all-dependencies或删掉vendor/+composer.lock再composer install - 用
composer show vendor/package查当前实际安装版本,再对比composer why vendor/package看谁把它带进来的 —— 往往是某个子依赖锁死了它 - 别忽略
minimum-stability设置:如果设成stable,而你要的版本是dev-master或beta,那再宽的约束也没用
生产环境该不该提交 composer.lock
应该,而且必须提交。它不是“可选配置”,而是部署一致性保障的核心文件。
- 没有
composer.lock,不同机器上composer install可能装出完全不同版本的依赖,连^1.2.3都可能在 CI 和线上跑出两个结果 -
composer install会严格按 lock 文件安装,无视composer.json里的版本范围;而composer update才会重新计算并更新 lock - 团队协作时,有人
update后忘了git add composer.lock,就会导致别人install出错 —— 建议在 CI 加一步校验:composer install --dry-run
真正容易被忽略的是:lock 文件里记录了每个包的 dist(zip/tar 包)哈希值,一旦源站分发的归档内容变了(比如 packagist 被污染),Composer 会拒绝安装 —— 这个保护机制只有 lock 文件存在时才生效。










