prefer-stable仅在多个满足约束的版本共存时优先选稳定版,不强制排除dev包;它必须与minimum-stability配合使用,且修改后需运行composer update才生效。

prefer-stable 不能阻止 dev 包安装,只能影响排序
很多人开了 prefer-stable: true 后发现 vendor 里还是有 dev-main 或 2.0.0-rc.1,就以为配置失效了。其实它只在「多个满足约束的版本同时存在」时起作用。比如 "monolog/monolog": "^3.0" 同时匹配 3.1.0(stable)和 3.2.0-beta.1(beta),这时 prefer-stable 才会让 Composer 选前者。
以下情况它完全不干预:
- 你在
require里直接写了"some/pkg": "dev-main"—— 显式指定,Composer 照装 - 某个依赖包自身声明了
"minimum-stability": "dev",且没设prefer-stable,它的子依赖就可能带出dev版本 -
composer.lock已锁定dev-develop,而你只运行composer install—— 它不会重解,只会照搬 lock 文件
必须配合 minimum-stability 才有意义
prefer-stable 是偏好,minimum-stability 才是门槛。单独设 prefer-stable: true 而不设 minimum-stability,在 Composer 2.2+ 中等价于 "minimum-stability": "stable",但这是隐式行为,容易误判。
推荐显式写全:
{
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"php": "^8.1",
"monolog/monolog": "^3.0"
}
}
这样 ^3.0 就只会在 3.x 的 stable 版本中选,跳过所有 -beta、-rc、dev- 分支。
注意:minimum-stability 是小写字符串,可选值为 stable、RC、beta、alpha、dev;其中 RC 必须大写,否则报错。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
改完 composer.json 后必须运行 composer update
修改 composer.json 中的 prefer-stable 或 minimum-stability,不会自动刷新已安装的包。已有 vendor/ 下的不稳定版本不会被替换,composer install 也完全无视这些新配置。
必须执行:
-
composer update—— 全量重解依赖并更新composer.lock - 或更安全的:
composer update --lock—— 只更新 lock 文件,不碰 vendor(适合 CI 环境验证) - 如只想更新某几个包:
composer update monolog/monolog symfony/console,避免牵连其他依赖
临时启用可加命令行参数:composer update --prefer-stable,但该选项仅对本次生效,不写入配置。
为什么用了 prefer-stable 还会装到 beta 版?检查这三处
常见漏点比配置本身更容易导致意外安装非稳定版:
-
require-dev里的包没清理:比如phpunit/phpunit或phpstan/phpstan自身依赖大量dev版本,上线前务必用composer install --no-dev - 某个
require条目带了@beta后缀却没注意空格:"symfony/console": "^6.4 @beta"(错误,多了一个空格)→ 正确应为"^6.4@beta" - 用了
replace或provide字段引入了虚拟包,而提供者本身是dev分支,这种间接依赖很难被prefer-stable拦住
最稳妥的验证方式是运行 composer show vendor/package,看输出里哪些版本被标记为 stable,再对比 composer.lock 中实际锁定的版本号 —— 不一致说明有某处绕过了稳定性策略。










