应使用composer run或composer [script-name]替代已弃用的composer run-script;脚本名须与composer.json中scripts键严格一致(区分大小写、含连字符/冒号时需加引号),传参必须用--分隔,执行目录为项目根,PHP脚本需手动引入vendor/autoload.php。

别用 composer run-script,现在该用 composer run 或直接 composer [script-name] —— 它只是个已弃用的别名,执行效果一样但会报警告,CI 日志里看着烦,新项目没必要碰。
怎么触发自定义脚本才不报错
脚本名必须和 composer.json 里 scripts 下的键**完全一致**,大小写、连字符、冒号一个都不能错。比如定义了 "test:unit",就不能写 composer test:unit(会当 Composer 命令解析),得用 composer run-script "test:unit",Windows 下双引号不能省。
- 先运行
composer run --list看当前有哪些可用脚本,这是最靠谱的验证方式 - 检查
composer.json中scripts是顶层字段,没被缩进到require或其他块里 - 如果脚本名含空格或中文标点,基本注定失败;改用下划线或连字符,别妥协
- 脚本未定义时错误是
Script not found: xxx,不是权限或路径问题,别往别处查
参数怎么传进去才生效
composer run test -- --filter=MyTest 这个中间的 -- 不是可选的,它是硬性分隔符。漏掉它,--filter 就会被 Composer 当作自己的选项吃掉,phpunit 根本收不到。
- 脚本值是字符串(如
"test": "vendor/bin/phpunit"),参数透传后靠 shell 解析,注意引号嵌套:比如要传带空格的路径,得写成composer run test -- --filter="My Test" - 脚本值是数组(如
"test": ["@php", "vendor/bin/phpunit"]),参数会原样追加到数组末尾,更安全,推荐 - PHP callable 脚本(如
"check": "My\Script::run")会把--后参数塞进$argv,但索引从 1 开始(0 是 PHP 可执行路径),建议优先读$_SERVER['COMPOSER_ARGS']
为什么脚本执行没输出或卡住
Composer 默认捕获子进程 stdout/stderr,只在失败时吐最后几行。像 php -S localhost:8000 这种长期运行的服务,容易被误判为“卡死”,实际只是没输出。
- 加
-v查看详细日志:composer run dev-start -v,能看到真实执行路径和环境变量 - 确认脚本是否真的在项目根目录运行 —— 所有
scripts都以composer.json所在目录为 CWD,不是你当前 shell 的位置 - 依赖
vendor/bin/下命令时,别写phpunit,写./vendor/bin/phpunit,避免 CI 环境 PATH 不一致 - PHP 脚本里要用类?第一行必须
require __DIR__ . '/vendor/autoload.php';,不然Class not found是静默失败,不会报错
真正难搞的从来不是语法,而是执行上下文:PATH 被重置、工作目录固定、autoload 不自动加载、环境变量不继承 —— 这些细节不显式处理,本地能跑,CI 必挂。


















