Composer scripts中执行PHP文件需手动引入autoload.php并声明"args":true以传参,调试时用2>&1或脚本内开启错误报告,失败时须显式exit($code)确保退出码传递。

scripts字段里怎么写才能让Composer执行PHP文件
直接写 php script.php 是最简单的方式,但要注意路径和执行权限。Composer 的 scripts 本质是 shell 命令,它不自动帮你加载 Composer 自动加载器(autoload),所以脚本里用到的类会报 Class not found 错误。
- 推荐把自定义脚本放在项目根目录下的
scripts/子目录,比如scripts/deploy.php - 在
composer.json中这样写:"scripts": { "deploy": "php scripts/deploy.php" } - 脚本开头必须手动引入 autoload:
<?php require __DIR__ . '/vendor/autoload.php'; // 后续代码可安全使用 Symfony\Component\Console\Application 等
- 如果脚本需要访问 Composer 的运行上下文(如当前 package 名、版本),得改用
EventDispatcher方式 —— 这属于进阶用法,普通场景不需要
为什么用 php -d display_errors=1 调试时仍看不到错误
因为 Composer 默认静默捕获子进程的 stderr,即使你加了 -d display_errors=1,PHP 的 Parse Error 或 Fatal Error 也不会打印到终端。这不是 PHP 配置问题,而是 Composer 的执行封装机制导致的。
- 临时解决:在命令末尾加
2>&1强制合并错误流,例如:"dev-test": "php -d display_errors=1 scripts/test.php 2>&1"
- 更可靠的做法是在脚本内部开启错误报告:
error_reporting(E_ALL); ini_set('display_errors', '1'); - 注意:生产环境脚本不应依赖
display_errors=1,而应记录日志或抛出异常由 Composer 捕获
scripts中调用的PHP脚本如何接收参数
Composer 不解析脚本参数,"run": "php script.php --foo bar" 里的 --foo bar 会原样传给 PHP 进程,但 $argv 是可用的 —— 关键是别指望 Composer 帮你做参数绑定或验证。
-
$argv[0]是script.php,$argv[1]开始才是你传的参数 - 如果想支持类似
composer run -- --env=prod的写法,必须在composer.json中声明pass-thru:"scripts": { "run": { "script": "php scripts/run.php", "description": "Run custom logic", "args": true } }然后执行composer run -- --env=prod - 不加
"args": true,--后面的内容会被 Composer 忽略,不会传进$argv
scripts执行失败时退出码没被正确传递
默认情况下,Composer 对脚本返回值比较“宽容”:即使你的 PHP 脚本 exit(1),Composer 也可能不报错、不中断后续流程。这是因为它只检查进程是否崩溃,而不校验退出码。
立即学习“PHP免费学习笔记(深入)”;
- 确保脚本末尾显式调用
exit($code),不要只靠异常未捕获来触发失败 - 在
composer.json中启用严格模式:"config": { "process-timeout": 300, "use-include-path": false, "discard-changes": true }但这对 exit code 无影响;真正起作用的是——别用|| true这类 shell 技巧掩盖失败 - CI/CD 中判断是否成功,应以
composer run xxx命令本身的退出码为准,而不是看输出内容
实际用的时候最容易漏掉的是 autoload 引入和 "args": true 声明,这两处一错,脚本要么跑不起来,要么收不到参数,但错误信息还不明显。



















