composer install 和 composer update 的根本区别在于是否读取并尊重 composer.lock 文件:install 严格按 lock 安装确定版本,确保环境一致;update 忽略 lock,重解依赖并强制更新 lock,可能引入不兼容变更。

composer install 和 composer update 的行为差异,只取决于一件事:是否读取并尊重 composer.lock 文件。用错命令,轻则本地和 CI 装出的 vendor/ 不一致,重则线上报 Class not found 或 Call to undefined method。
composer install 只认 lock 文件,不看 composer.json 的约束
只要 composer.lock 存在,composer install 就完全跳过 composer.json 里的 ^2.1、dev-main 甚至 * 这类写法——它只按 lock 里记录的精确版本号、哈希值、源地址下载解压。
- 有
composer.lock→ 直接装,不联网求解,不改 lock,快且确定 - 没有
composer.lock→ 退化为首次解析:读composer.json,跑依赖求解器,生成新 lock(仅应发生在项目初始化) - 改了
composer.json(比如加了"monolog/monolog": "^3.0"),但没跑update,再执行install没反应——它不会“自动同步” -
composer install --no-dev是生产部署标准操作;它只跳过安装require-dev下的包,不影响主依赖的复现逻辑
composer update 必然重算整个依赖图,且强制覆盖 lock
composer update 的本质是丢掉 composer.lock,重新跑一次 SAT 求解器:联网查 Packagist、校验 PHP 版本/扩展/子依赖约束、递归解决冲突,最后写入新 lock。它不是“升级你改过的包”,而是“重开一张处方”。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 默认行为:全量重算,哪怕只改了一行
composer.json,也会连带升级symfony/polyfill、psr/cache等间接依赖 - 想只更新某个包?必须显式指定:
composer update monolog/monolog,否则就是“顺手 upgrade 了整个生态” -
composer update --dry-run是必做动作,先看清会动哪些包、升到什么版本,再决定是否执行 -
composer update --no-dev仍会重算全部依赖(包括被 require 包间接依赖的 dev-only 包),只是最后不装而已——它不安全,别在服务器上跑
为什么删掉 composer.lock 再 run install 是高危操作
这等价于主动放弃环境一致性保障。一旦 composer.lock 被删或没提交到 Git,所有人的 composer install 都会退化成随机快照:今天装的是 monolog/monolog v2.10.0,明天可能是 v2.11.1,哪怕 composer.json 里写的仍是 ^2.10。
- 团队协作中,
composer.lock必须提交 Git;CI 流水线发现 lock 被修改但未 commit,应直接失败阻断 - 有人手动删了 lock 里
require-dev块“减小体积”,结果composer install --no-dev失败——因为 dev 块虽不装,但它的存在影响主依赖的解析路径 - PHP 升级后
update失败?大概率是config.platform.php还锁在旧版,需先改配置再试
最易被忽略的一点:很多人以为 install 会“检查远程是否有新版”,其实它从不联网验证——只要 lock 存在,就无条件信任并执行。依赖是否过期,只能靠人主动 update 并验证。

















