默认情况下 composer install 严格按 composer.lock 安装且不修改它;防止意外更新 lock 的核心是禁用 composer update、校验 Git 状态、CI 中强制检查 diff 并拒绝变更。

composer install 时跳过更新 composer.lock
默认情况下,composer install 会严格按 composer.lock 安装依赖,不读取 composer.json 的新版本约束——这本身就是“禁止修改 lock 文件”的行为。但很多人误以为它会自动更新 lock,其实是混淆了 composer update 的作用。
真正要防的是:有人不小心运行 composer update 或带参数的 composer install --update-with-dependencies 等命令,导致 lock 被重写。
- CI/CD 流程中只允许用
composer install,严禁composer update - 在项目根目录加只读权限(仅限开发机自查):
chmod 444 composer.lock;CI 中不推荐,可能被 Composer 自动忽略或报错 - Git 预提交钩子可校验 lock 是否被改动,但无法阻止本地执行
composer update
如何让 composer update 不碰 composer.lock?
它本来就不会“不碰”——composer update 的核心职责就是更新 lock。所以这个问题本质是:如何避免意外触发更新?
没有开关能“禁用 update 修改 lock”,只有控制输入和流程:
- 删掉
composer.lock后再运行composer install,会生成新 lock —— 这不是“禁止”,而是彻底放弃锁定 -
composer update --dry-run可预览变更,但不写入 lock;适合人工确认后再决定是否真跑 - 指定包名更新(如
composer update monolog/monolog)仍会重写整个 lock 文件,只是内容范围受限
CI 中确保 lock 文件不被覆盖的硬性做法
很多团队发现 CI 构建后 lock 文件变了,通常是因为构建脚本里混用了 composer update 或没检查 lock 是否已提交。
- CI 脚本第一行加校验:
git diff --quiet composer.lock || (echo "composer.lock changed! Commit it first."; exit 1) - 始终用
composer install --no-interaction --prefer-dist --optimize-autoloader,不加--update类参数 - 如果项目使用
composer install --ignore-platform-reqs,注意某些扩展缺失可能导致依赖解析失败,间接触发 fallback 行为(极少见,但会绕过 lock 的 PHP 版本约束)
composer.json 里的 lock 相关配置其实不存在
Composer 没有类似 "lock": false 这样的配置项。所有锁定逻辑都由是否存在 composer.lock 文件 + 执行的命令共同决定。
有人尝试在 composer.json 加 "config": { "lock": false },这不会生效,Composer 会静默忽略。
- 唯一影响 lock 行为的 config 是
"platform"(用于模拟平台环境),但它只改变依赖解析结果,不阻止 lock 写入 -
composer validate可检查composer.json和composer.lock是否一致,建议加入 pre-commit 或 CI - 多人协作时,
composer.lock必须提交进 Git;不提交 = 主动放弃版本锁定
composer update 的那一刻。










