必须用-vvv才能看到真实错误,因其原样透出子进程stderr,显示Fatal error、ParseError等被默认吞掉的崩溃信息,而-v和-vv仅显示表层动作。

脚本执行失败只显示 Script failed,根本不是脚本本身写错了,而是 Composer 默认把子进程的 stderr 吞掉了——你看到的只是退出码 1,真实错误(比如 Fatal error: Uncaught Error:、ParseError、Class not found)全被藏起来了。
必须用 -vvv 才能看到真实报错
只有 -vvv 会完整打印每条执行的脚本命令、环境变量、以及子进程崩溃时原样透出的 stderr。加 -v 或 -vv 都没用,它们只显示“正在运行 post-autoload-dump”,不显示 PHP 解析失败那一行。
- 运行
composer install -vvv或composer run-script xxx -vvv,直接翻到输出末尾,找以Script xxx handling yyy returned with error code 1结尾的那几行,再往上扫——真实错误就在它前面一两行 - 常见真凶:
Fatal error: Uncaught Error: Call to undefined function foo()、ParseError: syntax error, unexpected '}'、Class 'App\Console\Commands\MyCommand' not found - 如果脚本是独立 PHP 文件(如
scripts/deploy.php),检查文件开头是否有#!/usr/bin/env php,且 Linux/macOS 下需有可执行权限:chmod +x scripts/deploy.php - Windows 用户别折腾 shebang,直接在
composer.json里写"php scripts/deploy.php",避免系统找不到解释器
post-install-cmd 和 post-update-cmd 报错怎么定位
这类钩子脚本常被当成“自动流程”忽略,但一旦失败,-vvv 输出里会明确标出执行路径和 CWD(当前工作目录)。关键看它实际运行时的上下文是否符合预期。
- 确认脚本路径是相对
composer.json还是绝对路径;vendor/bin/phpunit在某些 CI 环境下可能因PATH未包含vendor/bin而找不到 - 脚本里用了
__DIR__或getcwd()?post-install-cmd的 CWD 是项目根目录,但某些插件或自定义 installer 可能会临时切换目录 - 如果脚本依赖环境变量(如
APP_ENV),-vvv会列出全部环境变量,检查是否缺失或值为空 - 临时绕过:加
--no-scripts测试是否纯脚本问题;确认后,再针对性修脚本而非关钩子
脚本里调用 php 命令失败的典型陷阱
很多自定义脚本会手动执行 php some-file.php,但这个 php 可能不是你预期的那个版本或配置。
- 检查 CLI PHP 版本:
php -v,确保和项目要求一致;某些脚本会因declare(strict_types=1)在低版本 PHP 下直接 fatal - 确认
memory_limit足够:php -r "echo ini_get('memory_limit');",脚本加载大量类时容易爆内存,报错却只显示Script failed - 脚本里用了
exec()或shell_exec()?这些函数可能被禁用(disable_functions),-vvv不会显示该限制,但你会在真实 stderr 里看到Warning: exec() has been disabled - Linux/macOS 下,如果脚本是 ZIP 包解压来的(比如通过
composer global require安装的工具),vendor/bin/*可能丢失可执行位——chmod +x vendor/bin/xxx或在composer.json加post-install-cmd自动修复
真正卡住人的,往往不是脚本逻辑,而是 -vvv 没开、PHP 版本错配、或者 disable_functions 静默屏蔽了关键调用——这些全得靠 -vvv 下原始 stderr 才能揪出来。


















