prefer-stable必须置于composer.json根层级,与require同级;它不控制安装权限,仅在minimum-stability筛选出的候选版本中优先选择更稳定的版本。

prefer-stable 必须写在 composer.json 顶层,不是 config 下
很多人把 prefer-stable 错误地塞进 config 对象里,比如:
{
"config": {
"prefer-stable": true
}
}
这完全无效——Composer 会直接忽略它。它只认根级字段。
正确写法是和 require、minimum-stability 并列:
{
"prefer-stable": true,
"minimum-stability": "dev",
"require": {
"symfony/console": "^6.4"
}
}
-
prefer-stable是布尔值,只接受true或false(不写默认为false) - 它不控制“能不能装”,只影响“多个候选版本中选谁”
- 如果项目没设
minimum-stability,prefer-stable: true基本没效果,因为默认已限于 stable
为什么加了 prefer-stable 还装了 dev-main?
常见原因就三个,按优先级排查:
- 你的
require或某个依赖的composer.json显式写了"some/pkg": "dev-main"或"@dev"—— 显式指定稳定性永远高于prefer-stable - 上游包自身设了
"minimum-stability": "dev"但没配prefer-stable,它的子依赖可能把dev带进来 - 你只运行了
composer install,而composer.lock里原本就锁着dev-main——prefer-stable只在composer update或首次解析时起作用
想强制重选?删掉 composer.lock 或至少删掉对应包条目,再跑 composer update --with-dependencies。
prefer-stable 和 minimum-stability 怎么搭才合理
它们不是并列开关,而是「门槛 + 排序规则」的关系:
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
-
minimum-stability是过滤器:只允许稳定性 ≥ 该值的版本进入候选池(合法值:dev / alpha / beta / RC / stable) -
prefer-stable是排序器:在候选池里,同等满足约束的前提下,优先挑更稳定的那个
典型生产组合是:
{
"minimum-stability": "stable",
"prefer-stable": true
}
看起来冗余,但能防住两种漏网情况:
- 某依赖显式声明
"some/pkg": "@dev"(绕过minimum-stability,但prefer-stable仍可抑制其传播) - 未来某天你临时切到
"minimum-stability": "beta"调试,prefer-stable会自动兜底选stable而非beta
命令行临时启用 prefer-stable 更安全
CI 流水线或临时调试时,用 composer update --prefer-stable 比改配置更可控:
- 它只对本次生效,不影响本地开发习惯
- 能覆盖
composer.json里的配置(命令行参数优先级更高) - 适合加固关键环节,比如发布前最后一轮依赖检查
注意:composer config -g prefer-stable true 是无效的——Composer 不支持全局 prefer-stable 配置。
真正容易被忽略的是:prefer-stable 不改变 lock 文件的语义。一旦 composer.lock 锁定了一个 dev 版本,哪怕你改了配置、加了 --prefer-stable,composer install 也照装不动——它只管还原 lock,不重新决策。










