--prefer-stable是临时排序偏好,仅在多个满足约束的合法候选版本中优先选stable版;它不拦截显式声明的dev/main或已锁在composer.lock中的非稳定版本,且需配合minimum-stability才能真正生效。

直接结论: --prefer-stable 是一次性开关,只在当前命令生效,它不改变项目配置,也不拦截已显式声明的不稳定版本(如 dev-main 或 @beta)——它只在多个满足约束的候选版本中,把 stable 版本排在前面。
什么时候用 --prefer-stable 才有效?
它只在 Composer 解析出多个合法版本时起作用,比如你写 "monolog/monolog": "^3.0",而该包同时有 3.5.0(stable)和 3.6.0-rc1(RC)可用,--prefer-stable 会让 Composer 选 3.5.0。
- 如果约束本身已锁定不稳定版本(如
"monolog/monolog": "dev-main"),--prefer-stable完全无效 - 如果
composer.lock里已锁死dev-main,运行composer install --prefer-stable不会重选,照样装 dev - 它对子依赖也生效,但前提是那些子依赖没在自己的
composer.json里设"minimum-stability": "dev"—— 那会局部覆盖你的偏好
--prefer-stable 和 "prefer-stable": true 的区别
命令行参数是临时的,配置项是持久的,但二者行为一致。关键差异在于生效范围和维护成本:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
composer update --prefer-stable:适合 CI 流水线加固、临时验证某次更新是否引入不稳定包 -
"prefer-stable": true写进composer.json根级:后续所有composer update默认带上该偏好,但必须配合"minimum-stability": "stable"才真正拦住非 stable 包 - 如果命令行和配置同时存在,命令行参数会覆盖配置(Composer 行为)
为什么加了 --prefer-stable 还装了 beta?检查这三处
不是参数失效,而是它根本没机会介入选择逻辑:
- 你在
require或require-dev里写了"some/pkg": "^2.0@beta"或"some/pkg": "dev-main"—— 这是硬性指令,Composer 直接执行 -
composer.lock里存着旧的beta或dev记录,而你只跑composer install;得先composer update --lock或删锁文件重建 - 某个依赖包自身声明了
"minimum-stability": "dev",它的子依赖可能跳出你的控制;此时需在require中显式加@stable,例如"vendor/subpkg": "^1.2@stable"
验证 --prefer-stable 是否真起作用
别看 composer.lock 文件内容,直接查解析结果:
- 运行
composer show monolog/monolog(把包名换成你要查的) - 重点看输出里的 version 字段:如果出现
dev-main、2.0.0-beta1、3.4.x-dev这类字样,说明没拦住 - 此时不要急着加参数,先
grep -n "@beta\|@dev\|dev-" composer.json检查显式声明
真正难处理的永远不是参数怎么写,而是依赖树里谁悄悄开了后门——比如一个二级依赖把自己的 minimum-stability 设成 dev,再通过宽松约束把 unstable 包带进来。这种问题不会报错,但会让 --prefer-stable 形同虚设。

















