必须用 -vvv 才能显示脚本真实错误;常见原因包括 proc_get_status 被禁用、autoload 未生效、shebang 路径错误或 PHP 版本不匹配。

脚本失败只显示“Script failed”,怎么看到真实错误
Composer 默认会吞掉子进程的 stderr,你只能看到 Script xxx handling yyy returned with error code 1,却不知道哪行 PHP 崩了、有没有 Fatal error 或 Class not found。关键不是加日志,而是让底层命令的错误原样透出。
必须用 -vvv:只有它会显示每条执行的脚本命令、完整环境变量、及其退出时的原始 stderr。其他级别(-v 或 --verbose)都不够。
- 常见真实错误只在
-vvv下可见:Fatal error: Uncaught Error:、ParseError、Undefined variable - 如果脚本是 PHP 文件,检查开头是否有
#!/usr/bin/env php,且 Linux/macOS 下需有可执行权限(chmod +x script.php) - Windows 不认 shebang,推荐显式写
"php script.php",避免系统找不到解释器
post-install-cmd 或 post-update-cmd 报错 proc_get_status 被禁用
这类脚本失败常伴随 Call to undefined function proc_get_status() 或 proc_open() has been disabled for security reasons。这不是 Composer 配置问题,而是 PHP 运行环境主动禁用了进程控制函数。
Composer 依赖 proc_open 启动子进程,而 proc_get_status 是其配套状态检查函数,两者常被一并禁用。共享主机尤其喜欢全局禁用整套函数(exec、shell_exec、proc_open、proc_get_status)。
- 确认被禁用函数:运行
php -i | grep disable_functions,看输出是否含proc_get_status和proc_open - 修改
php.ini:找到 CLI 和 Web 环境各自使用的配置文件(php --ini查路径),从disable_functions行中删掉这两个函数,再重启 PHP 服务 - 无权改
php.ini?临时绕过:用composer install --no-scripts跳过所有钩子;或先本地装好vendor/再上传,彻底避开远程执行
脚本里 require 的类找不到,autoload 没生效
比如自定义的 scripts/post-install.php 里写了 new AppInstaller() 却报 Class 'AppInstaller' not found,这通常不是类不存在,而是自动加载根本没加载进来——因为脚本执行时 vendor/autoload.php 没被引入,或 PSR-4 配置压根没生效。
第一反应不是改类名,而是让 Composer 自己说清楚它到底扫了什么:composer dump-autoload -v 会逐行打印扫描目录、匹配类、跳过文件及 PSR-4 前缀识别情况。如果输出里压根没出现 App,说明 composer.json 的 autoload 配置无效。
- 检查
composer.json中autoload是否格式正确(漏逗号、多逗号、引号不闭合) - PSR-4 键值末尾必须带反斜杠:
"App\": "src/",不能写成"App": "src/" - 路径不能用相对写法:
"./src/"或../src/Composer 不认,只接受"src/" - 脚本自身必须手动引入自动加载器:
require __DIR__ . '/vendor/autoload.php';—— 注意用__DIR__,别用./vendor/autoload.php
脚本执行后提示 “No such file or directory”,但权限明明是可执行的
现象:运行 ls -l vendor/bin/my-script 显示 -rwxr-xr-x(有 x 位),但执行仍报 No such file or directory。这不是权限问题,而是 shebang 指向了不存在的解释器路径。
Linux/macOS 下,shebang 行(如 #!/usr/bin/env php)会被内核解析并调用对应程序。如果该路径下没有 php,或者 env 找不到它,就会触发这个错误,且不提示具体原因。
- 验证方法:运行
head -n1 vendor/bin/my-script,看第一行是不是#!/usr/bin/env php - 再运行
which php,确认 CLI PHP 实际路径;若不一致(比如脚本里写的是/opt/php81/bin/php,而which php返回/usr/bin/php),就必然失败 - 修复方式:要么改脚本 shebang 为绝对路径(
#!/usr/bin/php),要么统一 PHP 环境(如用update-alternatives或符号链接) - Windows 下完全不走 shebang,直接报“不是内部或外部命令”,此时应显式调用
php vendor/bin/my-script
脚本失败的真实原因往往藏在最不起眼的地方:一个没生效的 autoload 配置、一行错位的 shebang、或一个被面板悄悄降级的 PHP 版本。调试时别急着重装,先让 -vvv 说话,再查 phpinfo() 和 php --ini,最后盯住那行 head -n1 输出——多数时候,答案就在前三行里。











