
composer script 命令后跟的参数去哪儿了
默认情况下,composer run-script 后面加的参数,**不会自动透传给脚本命令本身**。比如你写 composer run-script test — –env=prod,但脚本里用 php test.php $1 是拿不到 –env=prod 的——因为 Composer 拦截了 — 之后的内容,只在自己内部处理,不转发。
真正生效的方式只有一种:在 composer.json 的脚本定义里显式启用参数透传。
必须用 php script.php @phpscript 这类带 @phpscript 占位符的写法(或等价的 @php)必须在命令末尾加 — 分隔符,否则参数会被 Composer 当作自己的选项解析scripts 中的值如果是字符串,且含 @php 或 @phpscript,Composer 才会把 — 后的参数原样塞进 PHP 进程的 $argv
怎么让自定义 PHP 脚本能接收到 –env=prod 这类参数
关键不在 PHP 脚本怎么写,而在 composer.json 怎么配。下面这个配置才是有效的:
"scripts": { "test": "php test.php @phpscript"}
然后执行:
composer run-script test — –env=prod –debug
这时 test.php 中的 $argv 才会是:[‘test.php’, ‘–env=prod’, ‘–debug’]。
如果写成 "test": "php test.php",无论你怎么加 –,参数都进不了 $argv@phpscript 和 @php 效果一样,都是告诉 Composer:“接下来要调用 PHP,并把后续参数透传过去”Windows 下同样适用,但注意 CMD 对 = 和引号的解析更敏感,建议用 PowerShell 或加双引号包裹参数,如 — "–env=prod"
为什么 bin/console foo:bar –env=prod 在 composer script 里会失败
因为 bin/console 是 Symfony 控制台应用,它依赖完整的 CLI 环境和 autoloader,而 Composer 默认调用脚本时,autoload 可能未加载、CWD 可能不对、环境变量也可能缺失。
直接写 "dev:clear": "bin/console cache:clear –env=dev" 大概率报错:Class ‘Symfony\Component\Console\Application’ not found正确做法是用 @php 显式触发,并确保 autoloader 可用:"dev:clear": "php bin/console cache:clear @php –env=dev"更稳妥的是用 Composer 内置的 php 命令封装(它会自动 require autoload):"dev:clear": "@php bin/console cache:clear –env=dev"注意:这里 –env=dev 是传给 bin/console 的,不是给 Composer 的,所以不能加额外的 — 分隔符
传参时容易忽略的路径和环境差异
即使参数透传成功,脚本行为仍可能出人意料——根源常在工作目录和加载上下文。
Composer 执行脚本时的 getcwd() 是项目根目录,但如果你的脚本里用了相对路径(如 require ‘./config/app.php’),而实际运行时 CWD 是 vendor/bin,就会失败推荐在脚本开头统一设置:chdir(dirname(__DIR__)); 或用 __DIR__ 构建绝对路径$_SERVER[‘argv’] 和 $argv 在某些 SAPI(如 cgi-fcgi)下可能为空,优先用 $argv,且不要依赖 $_SERVER 的 CLI 相关字段如果脚本需要读取 .env,别假设 Dotenv::createUnsafeImmutable() 会自动从项目根找——得显式传路径:Dotenv::createUnsafeImmutable(__DIR__.’/..’)
参数能传进去只是第一步,脚本能稳定拿到、解析、用对,才真正算通了。

评论(0)