composer 无 --stop-on-failure 开关,脚本是否中止取决于退出码是否被 shell 捕获、autoload 是否正确加载、脚本名是否精确匹配;需用 set -e 或 && || 显式控制流程。

Composer 本身没有 run-script --stop-on-failure 这种命令,也不存在全局开关让所有脚本自动中止后续执行——出错是否停止,完全取决于你写的脚本怎么退出、以及调用它的上下文怎么响应退出码。
composer run-script 为什么没停,其实是 shell 没看 $?
当你在 shell 脚本里写:
composer run-script pre-install-cmd composer install
即使 pre-install-cmd 里 exit(1) 或抛出异常,第二行 composer install 仍会执行。这不是 Composer “没停”,而是 bash 默认忽略上一条命令的退出状态。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
-
set -e放在脚本开头最简单有效:任何命令返回非 0,脚本立刻终止 - 不用
set -e?那就显式链式判断:composer run-script pre-install-cmd && composer install || exit 1 - CI 配置(如
.gitlab-ci.yml)里别写|| true,它会把错误吞掉,让你误以为流程成功 - Git Bash / Windows 用户注意:
set -e在某些子 shell 下可能不生效,优先用&& ||显式写死
PHP 脚本里 exit(1) 不起作用?检查 autoload 和执行路径
很多“脚本报错但 run-script 没中断”是因为 PHP 类根本没加载成功,连 exit() 都没走到,直接 Fatal error: Class not found 后 Composer 就记下错误码 255 并继续——但它其实已经失败了,只是你没看到真实报错。
- PHP 脚本第一行必须加:
require __DIR__ . '/vendor/autoload.php';,否则所有类都不可用 - 不要依赖
composer.json的autoload-dev自动加载回调脚本;它只在composer install --dev时注册,run-script不触发重载 - 脚本路径别写
./scripts/check.php,run-script的当前工作目录不保证是项目根;统一用__FILE__或getcwd()定位 - 调试时加
--verbose:composer run-script check --verbose,否则 stderr 被静默吞掉,只剩一句 “Script … returned with error code 1”
脚本名拼错 or 参数传错,也会导致“看似没停”
比如你定义了 "pre-deploy": "App\Deploy::check",却执行 composer run-script predeploy(少了个短横),Composer 会说 Script not found 然后默默跳过——它不报错退出,后续命令照常运行。这容易被当成“没 stop”,其实是命令压根没执行。
- 永远先跑
composer run --list确认脚本名存在且拼写完全一致(大小写、短横、冒号都算) - 含冒号的脚本名(如
ci:lint)必须用双引号:composer run-script "ci:lint",Windows CMD 下不加就解析失败 - 要传参?中间必须有
--:composer run-script deploy -- --env=prod,漏掉它,--env就被 Composer 当作自身参数吃掉 - PHP 回调脚本收不到
--后的参数;得靠$_SERVER['COMPOSER_ARGS']或环境变量传,不能依赖$argv
真正决定“停不停”的,从来不是 Composer 的某个隐藏开关,而是退出码是否被上层捕获、autoload 是否就位、脚本名是否精确匹配——这三个点漏掉任何一个,都会让失败看起来像“悄悄溜走”。










