composer锁定依赖需同时满足:composer.json写三位完整版本号(如"2.9.1")、composer.lock提交至git、部署时运行composer install——三者缺一不可;否则版本仍可能漂移。

composer.json里写"2.9.1"不等于真锁死
很多人改完composer.json以为就锁定了,结果composer install还是装了2.9.2。根本原因是:双引号里的"2.9.1"在旧版 Composer(^2.9.1,允许补丁升级。真正生效的写法必须是不含任何符号的纯数字字符串,且三位完整——比如"monolog/monolog": "2.9.1",不能是"2.9"、"2.9.*"或带空格的"2.9.1 "。
常见错误现象:composer show monolog/monolog输出版本是2.9.2,但composer.json明明写了"2.9.1";或者composer update monolog/monolog提示Nothing to install or update,但composer update全量执行时它又升了。
- 验证是否真锁死:运行
composer show monolog/monolog,看versions行是否严格等于你写的字符串(注意有无v前缀、+git后缀) - 检查
composer.lock:搜索包名,确认"version": "2.9.1"字段存在,且"source": {"reference": "..."}"是确定 commit hash,不是dev-main之类动态引用 - 别信
composer require monolog/monolog:2.9.1——它默认加^,得手动打开composer.json删掉那个插入符
composer.lock冲突不是文件差异,是流程断了
中文团队协作中出现“依赖不一致”,90% 不是 Git 合并出错,而是有人本地执行了composer update、删了composer.lock重生成、或 CI 脚本偷偷用了composer update。一旦composer.lock没提交、被.gitignore过滤、或 PHP 版本不一致(比如你用 8.2,同事用 7.4),composer install就会退化为重新跑 SAT 求解器——哪怕composer.json完全一样,也可能装出不同版本的psr/log或guzzlehttp/psr7。
- 强制校验对齐:在
composer.json顶层加"config": {"lock": true},这样只要composer.json和composer.lock不匹配,composer install立刻报错,例如The lock file does not contain the required package "guzzlehttp/guzzle" - CI 第一步必须检查:
ls -la composer.lock确认文件存在,再比对git log -1 --format=%H -- composer.lock确保它来自当前 commit - 禁用 vendor 缓存:GitHub Actions 中显式设
cache: false,否则可能读到上个分支缓存的过期composer.lock
想锁定 dev 分支?commit hash 才算数
写"monolog/monolog": "dev-main"不是锁定,是放任漂移——每次composer update都可能拉最新 HEAD。中文环境下尤其危险:有人提 PR 改了 main 分支,你本地composer install却悄无声息地升级了依赖,连 diff 都看不出。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
真正锁定某次提交,必须用dev-main#abc1234格式,其中abc1234是真实 commit hash。如果分支名含斜杠(如feature/login-flow),得 URL 编码成feature%2Flogin-flow,否则 Composer 解析失败。
- 查 commit hash:进对应仓库
git log -n 1 --format=%H,复制前 7 位即可 - 写法示例:
"monolog/monolog": "dev-main#f3a7b2c",不是"dev-main#f3a7b2c as 2.9.1"(后者只是别名,不阻止更新) - 验证方式:
composer show monolog/monolog输出的source reference必须和你填的 hash 完全一致
CI 和部署脚本里最常踩的坑
生产环境出问题,往往不是代码 bug,而是部署脚本里一句composer update或--no-lock直接绕过了所有锁定逻辑。中文团队常因“顺手更新一下”或“CI 缓存太旧”导致线上装错版本。
- 上线唯一可信命令:
composer install --no-dev --no-interaction --optimize-autoloader,绝不用update - 加一道保险:
composer install --locked——它会逐条校验composer.lock中每个包是否仍满足composer.json约束,不满足直接退出,不让你稀里糊涂上线 - CI 构建失败时别删
composer.lock重来:先跑composer why-not vendor/package:1.2.3定位阻塞链,再决定是调低 PHP 版本、改平台配置,还是协调其他成员同步更新
复杂点在于:锁定不是单点操作,是composer.json写死 + composer.lock提交 + 全流程install执行 + 环境统一(PHP/扩展/平台配置)四者咬合。漏掉任意一环,中文协作中那种“他能跑,我报错”的现象就必然重现。










