prefer-stable 是排序偏好而非锁死开关:它在满足依赖约束及 minimum-stability 底线前提下优先选 stable 版,无 stable 时仍会退至 rc/dev;其效果受 composer.lock 约束,需 composer update 才生效,且不覆盖 require 中显式指定的不稳定版本。

prefer-stable 是开关,不是锁死开关
prefer-stable 的作用很实在:它不禁止 dev/beta/alpha 版本,只在满足所有依赖约束的前提下,让 Composer 优先从可选版本中挑 stable 的。比如你写 "monolog/monolog": "^3.0",而当前有 3.5.0(stable)和 4.0.0-beta1(beta),prefer-stable 会让它选 3.5.0;但如果 ^3.0 范围内根本没 stable 版(比如只有 3.6.0-RC1 和 3.7.0-dev),它还是会装 RC 或 dev——只要满足约束、稳定性不低于 minimum-stability 设定的底线。
常见错误现象:
- 以为开了
"prefer-stable": true就绝对不装 beta,结果某包没 stable 版,还是装了 RC - 项目
"minimum-stability": "dev",但没配prefer-stable,结果laravel/framework被间接依赖拖进dev-main
minimum-stability 和 prefer-stable 的配合逻辑
minimum-stability 是准入门槛,prefer-stable 是排序偏好。两者必须一起看:
-
"minimum-stability": "stable"+"prefer-stable": true:效果等同于只允许 stable,prefer-stable实际无作用 -
"minimum-stability": "dev"+"prefer-stable": true:这才是典型场景——允许装 dev,但核心包(如symfony/console)大概率落到 stable 版本上 -
"minimum-stability": "beta"+"prefer-stable": true:会优先选 stable,但若无 stable,则 fallback 到 beta(不会跳到 alpha 或 dev)
注意:minimum-stability 是全局默认值,会被单个包的 stability flag 覆盖。比如你在 require 里写 "some/pkg": "dev-main",哪怕开了 prefer-stable,这个包也一定走 dev-main。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
composer install 不生效?先看 lock 文件有没有“记住”旧版本
你改了 composer.json 加上 "prefer-stable": true,再跑 composer install,结果发现某个包还是装了 4.0.0-dev——大概率是因为 composer.lock 里已经锁死了那个 dev 版本。
-
composer install永远以composer.lock为准,完全忽略composer.json里的prefer-stable配置变化 - 想让它重新评估,必须用
composer update(或加--with-dependencies) - 更稳妥的做法是删掉
composer.lock后再composer update,尤其当你刚改完minimum-stability或prefer-stable
顺带一提:如果某个包在 composer.lock 里是 dev-main,但你本地 composer.json 没显式声明它,那它其实是被某个间接依赖带进来的——用 composer why-not vendor/package:3.5.0 能快速定位谁在拦路。
临时生效比永久配置更安全
开发中偶尔要测 beta 版,又不想影响整个项目的稳定性策略,这时候别改 composer.json,直接命令行加参数:
-
composer require monolog/monolog:2.5.0-beta1 --stability=beta:只对这个包放宽,且只本次生效 -
composer update monolog/monolog --with-all-dependencies --stability=beta:更新时连带它的子依赖也允许 beta - 回退时,把版本改成
^2.5再composer update monolog/monolog,Composer 会自动降级并写入composer.lock
真正容易被忽略的是:一旦你在 require 里写了 @dev 或 dev-main 这类显式不稳定标识,prefer-stable 就彻底失效——它只管“在多个合法选项里挑 stable”,不负责覆盖你亲手写的明确指令。










