必须用composer install而非update来克隆环境,因install严格按composer.lock中记录的精确版本、commit hash、URL和校验和安装,无视composer.json约束;update则忽略lock、重算依赖,导致版本漂移和运行时错误。

必须用 composer install,且项目根目录下必须存在未被修改的 composer.lock 文件——这是唯一能还原原项目依赖环境的方式;composer update 会跳过 lock、重算依赖,导致版本漂移和运行时错误。
为什么 composer install 才是“克隆”,而 composer update 是“重建”
composer install 的行为是查表执行:它只读 composer.lock,按里面记录的每个包的精确版本号、Git commit hash(对 dev 包)、dist URL 和校验和下载安装,完全无视 composer.json 中的 ^2.0 或 ~3.5 这类范围约束。这才能保证你装的 guzzlehttp/guzzle 是 7.8.1 而不是 7.9.0,哪怕两者都满足 ^7.0。
composer update 则相反:它忽略 composer.lock,重新解析整个依赖图,求解“当前环境下满足所有约束的最新兼容版本”,并覆盖写入新 composer.lock。结果就是——你本地跑通了,CI 报 Class not found,线上偶发 ArgumentCountError。
- 常见错误现象:
git clone后直接composer update,然后发现vendor/里多了几个没在原项目中见过的包 - CI 流水线中误用
update→ 构建产物不一致,测试通过但线上崩溃 - 团队里有人只提交了
composer.json却漏掉lock→ 其他人install时自动退化为update,环境悄然分裂
composer install 执行前必须确认的三件事
缺一不可,否则大概率失败或装错:
-
composer.lock文件必须存在且未被.gitignore忽略(检查命令:ls -la | grep composer.lock;若不存在,需先在原项目中运行composer update --lock生成) -
vendor/目录必须为空或不存在(composer install不会清理已有文件,混杂加载会导致 Autoload error 或类行为错乱) - PHP 版本和已启用扩展必须满足
composer.lock中"platform"字段声明(例如 lock 顶部有"php": ">=8.1.0",而你本地是 PHP 7.4,则会跳过部分包甚至报Your requirements could not be resolved)
同步私有包或自定义源时容易卡住的点
如果 composer.lock 里有来自 GitLab、私有 Satis 或本地路径的包,composer install 会严格按 lock 记录的源地址拉取——但它不会帮你配权限。
- 报
Cloning into ''或401 Unauthorized:说明缺少对应仓库的认证凭据,需提前在~/.composer/auth.json或项目级auth.json中配置 token - 使用
--repository-url参数临时指定源时,注意格式必须是合法 JSON(如{"type":"vcs","url":"/path/to/repo"})
真正难的不是记命令,而是让所有人理解:composer.lock 不是“生成物”,它是和 composer.json 平级的源码——一旦被手动编辑、忽略、或与 json 不同步,所有环境一致性就立刻失效,且问题往往延迟暴露在 CI 或上线后。











