不能手动改composer.lock,因其是带content-hash校验的依赖快照,非普通配置文件;手动修改会导致install失败、validate报错或平台扩展缺失。

composer install 本身不解决合并冲突,但它是在冲突解决后唯一能正确重建依赖一致性的命令——前提是 composer.json 已无冲突、composer.lock 是干净生成的。
为什么不能手动改 composer.lock?
Git 报 composer.lock 冲突时,本质是两个分支各自运行过 composer update 或增删包,导致哈希、嵌套依赖树、平台约束不一致。这个文件不是配置文件,而是安装快照,手动编辑极易出错:
• 改错一个 content-hash,composer install 直接报 Lock file operations: 1 install, 0 updates, 0 removals 却不装包
• 拆分或拼接 JSON 结构,会导致 composer validate 失败,甚至跳过某些 dev 包
• 忽略 platform 字段差异,可能在 CI 上装出缺少 ext-gd 的 vendor
合并后第一步:确认 composer.json 是否干净
composer.lock 冲突往往源于 composer.json 先有未合入的变更。必须先确保它已无冲突并符合预期:
- 运行
git status,检查是否只有composer.lock显示冲突,composer.json在工作区是 clean 状态 - 若
composer.json也有冲突,先手工合并或协商取舍(比如 PHP 版本约束、require/remove 的包列表) - 执行
composer validate,确认composer.json语法和字段合法;失败则说明config.platform写错位置或拼写错误
用 install + require/remove 替代 merge 或 update
多数场景下,不需要“合并 lock”,只需还原本分支应有的依赖状态:
- 暂存当前冲突的
composer.lock:git stash save "lock-conflict" - 检出主干的
composer.lock:git checkout main -- composer.lock - 运行
composer install—— 此时装的是主干依赖,干净无误 - 再执行本分支需要的变更:
composer require stripe/stripe-php:^12.0或composer remove phpunit/phpunit - Composer 自动重写
composer.lock,生成仅含本分支增量的新快照
注意:不要用 composer update,它会连带升级其他包;也不要删 lock 后直接 install,那会忽略 config.platform 和 require-dev 的精确控制。
CI/CD 中必须禁用 update,且验证 lock 存在
生产部署和 CI 流水线里,composer install 的可靠性完全依赖 lock 文件存在且未被破坏:
- 脚本开头加校验:
test -f composer.lock || { echo "ERROR: composer.lock missing"; exit 1; } - 固定使用:
composer install --no-dev --no-interaction --no-progress - 禁止在 CI 镜像中预装全局依赖或设置
minimum-stability,避免覆盖项目级约束 - 如果 CI 报
Package xyz has no installation candidates,大概率是composer.json里写了"repositories"但没提交,或镜像源未统一(比如本地用了阿里云,CI 还走 packagist.org)
真正容易被忽略的点是:即使 lock 文件存在,如果它是在不同 PHP 小版本下生成的(比如本地 "php": "8.1.10",CI 是 8.1.9),composer install 仍可能跳过平台扩展检测,导致运行时报 Class not found —— 所以 config.platform.php 必须写死到小版本,并在所有环境统一。











