composer install 不理会 composer.json 修改,因为它只读取 composer.lock 文件安装精确版本,完全忽略 composer.json 中新增、修改或删除的依赖声明,这是保障环境一致性的设计机制。

composer install 为什么“不理会”你改的 composer.json
因为 composer install 根本不读 composer.json 的版本约束,只要 composer.lock 存在,它就只按锁文件里写死的版本号、哈希值和源地址安装。你往 composer.json 里加了 "monolog/monolog": "^3.0",但没跑 composer update,install 就当那行不存在——它不是“装得慢”,是压根不看。
常见错误现象:
-
composer install后新包没出现,vendor 里还是老样子 - CI 报错
Class not found,但本地跑得好好的(composer.lock没提交或被.gitignore了) - 改完
composer.json立刻install,结果提示Package x is not installed(锁文件没更新,新依赖不在里面)
composer update 不生效的三种典型原因
它不是“没反应”,而是求解失败、被跳过、或根本没触发重算。最常被忽略的是平台约束和锁文件残留。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- PHP 版本不匹配:
composer.lock里记录的包是为 PHP 8.1 编译的,你在 PHP 8.2 下跑composer update,solver 直接跳过某些包,甚至报Your requirements could not be resolved—— 先检查"platform": {"php": "8.2"}是否已写入composer.json的config块 - 锁文件存在且未被强制覆盖:即使你改了
composer.json,composer update默认仍会基于当前composer.lock的状态做增量求解(尤其带--with-dependencies时),不一定拉到你预期的新版本;加--ignore-platform-reqs或删掉composer.lock再试,才能触发完整重算 - 用了
--no-dev但想升级 dev-only 包:比如phpunit/phpunit只在require-dev里,composer update --no-dev phpunit/phpunit会静默失败——必须去掉--no-dev才能解析和升级它
为什么 “只更新一个包” 也未必真只动一个
composer update vendor/package-name 看似精准,但 Composer 的依赖求解器不会孤立看待单个包。它会把整个依赖图重新载入,再以该包的新约束为起点,递归校验所有间接依赖是否仍满足条件。
- 不加
--with-dependencies:可能卡在“已满足”,子依赖(如symfony/polyfill)保持旧版,导致运行时行为不一致 - 加了
--with-dependencies:连带升级所有被该包直接或间接依赖的包,实际改动远超预期 - 通配符陷阱:
composer update "symfony/*"看似可控,但若其中某个包(如symfony/console)的约束宽泛("^5.4 || ^6.0"),它可能把整条链路推到 v6,而其他symfony/*包还没适配
CI/CD 和生产环境里,update 是高危操作
它不只是“慢”或“多装几个包”,而是彻底放弃可重现性。一旦 composer update 在部署脚本里执行,就等于把版本控制权交给 Packagist 当前镜像状态、网络延迟、甚至 solver 的随机回溯路径。
- 流水线中出现
composer update,意味着每次构建都可能得到不同vendor/,哪怕 commit hash 完全相同 - 线上服务器跑
update后没立刻git add composer.lock && git commit,下次部署就会丢失这次变更,且无法回滚到精确状态 -
composer install --no-dev是安全的复现操作;composer update --no-dev仍是危险的重算操作——它照常联网、校验、求解全部require,只是最后不装dev包而已
最易被忽略的一点:很多人以为 install 会“自动检测 composer.json 变更并同步”,其实它从不检测。依赖是否过期、是否兼容、是否需要升级,全靠人主动 update 并验证——锁文件不是监控探针,是快照契约。










