--locked 是生产环境唯一可信参数,它强制校验 composer.lock 存在、合法且与 composer.json 兼容,不满足则立即失败,绝不 fallback 或重建;配合精确版本号和 --no-dev 才构成完整锁定。

生产环境不能“禁用自动更新”,因为 Composer 本来就没有自动更新机制;真正要防的是人误执行 composer update,或因环境缺失导致 composer install 退化为更新行为。核心是让 composer install 严格按 composer.lock 执行,且不妥协、不 fallback、不生成新 lock。
为什么 --locked 是生产环境唯一可信参数
composer install --locked 不是“可选优化”,而是硬性校验开关:它要求 composer.lock 必须存在、非空、JSON 合法,并且所有包版本必须与 composer.json 中的约束兼容。一旦不满足,立即失败,绝不会静默重建或重写 lock 文件。
- 不加
--locked时,若composer.lock缺失或与composer.json不一致,composer install可能自动 fallback 到update行为(尤其旧版 Composer) -
--locked会拒绝所有干扰参数:--ignore-platform-reqs、--dry-run、--with-dependencies等均被禁止,避免绕过检查 - CI 流水线中加这一参数,等于给部署加了一道“锁文件存在性 + 内容一致性”双校验门
如何防止 composer.lock 被意外覆盖或忽略
高频事故不是 lock 文件被“修改”,而是它根本没进 Git,或在构建流程中被漏传。CI 构建阶段必须主动验证其状态。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 在 CI 脚本开头加:
git diff --quiet composer.lock || (echo "ERROR: composer.lock changed or uncommitted" && exit 1) - Docker 构建时确保
COPY composer.lock .在COPY composer.json .之后,且两者都在composer install前完成 - 本地开发提交前,运行
composer validate --strict,避免 JSON 格式错误导致 Composer 强制重建 lock - 不要对
composer.lock设置.gitignore,也不要在 CI 中用git clean -fdx清除它
精确版本号 + --no-dev 是锁定行为的两个支点
只靠 --locked 不够——如果 composer.json 里写的是 "monolog/monolog": "^2.9",那 lock 文件里哪怕记着 2.9.1,下次 composer update monolog/monolog 仍可能升到 2.10.0。
- 对关键包,改用无符号精确版本:
"monolog/monolog": "2.9.1",不是"2.9.1"加^,也不是简写"2.9" - 运行
composer update monolog/monolog同步该包到 lock 文件,确认packages字段中 version 字段值完全匹配 -
--no-dev不是性能选项,是安全边界:它跳过require-dev和autoload-dev,防止dump()等调试函数上线后冲突
权限与环境变量是最后一道防线
命令行参数可以写错,但操作系统级限制和环境变量几乎无法绕过。适合在容器或部署脚本中固化。
- 部署前导出:
COMPOSER_NO_INTERACTION=1(防卡住)、COMPOSER_DISABLE_XDEBUG=1(防加载失败) - 生产服务器上可对
composer命令做软链限制,例如只保留composer install的 wrapper,删掉update、require等子命令入口 - 某些团队会在
/usr/local/bin/composer上设为只读,或用chmod 555,虽不能阻止php composer.phar直接调用,但能拦截大部分误操作
最常被忽略的不是语法细节,而是 lock 文件与 PHP 版本的隐式绑定:从 PHP 8.1 升级到 8.2 后,composer.lock 里记录的某些扩展依赖(如 ext-gd 或 symfony/polyfill)可能不再兼容,--locked 会直接报错,此时必须回到开发环境重新 composer update 并提交新 lock——它不是缺陷,而是设计使然。










