脚本钩子报错主因是执行上下文缺失或环境不一致,需加 -v 查看真实 stderr 错误;重点关注报错前最后执行命令、autoload.php 是否存在、PHP 路径与权限、退出码非零及当前工作目录是否为项目根目录。

脚本钩子报错不是脚本写错了,而是执行上下文缺失或环境不一致。 直接看 Script xxx handling xxx failed 这行红字毫无意义——它只是 Composer 的“甩锅总结”,真实错误藏在被静默吞掉的 stderr 里。
加 -v 参数才能看到真实错误输出
Composer 默认把子进程的 stderr 全部吃掉,只留一个笼统失败提示。不加 -v 就调试,等于靠猜修电路。
- 必须用
composer run test -v或composer install -v重试,强制显示每条命令的完整执行路径和输出 - 重点盯住报错前最后一行实际执行的命令,比如
php ./tests/run.php—— 它才是真凶入口 - 如果输出里出现
sh: php: not found或'php' is not recognized,说明 shell 根本找不到php可执行文件,和脚本逻辑无关
autoload.php 是否存在决定类能否加载
很多脚本(尤其是 post-install-cmd、post-update-cmd)会在 vendor/autoload.php 尚未生成时就被触发。此时脚本里只要 new 一个类,立刻 Class not found。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 检查脚本是否依赖自动加载:如果
php scripts/check.php里有new App\SomeClass(),就必须确保vendor/autoload.php已就绪 - 把关键脚本挪到
post-autoload-dump钩子下——它保证 autoloader 已生成完毕 - 更稳妥的做法是在脚本开头加防护:
if (!file_exists('vendor/autoload.php')) { echo "autoload missing"; exit(1); }
PHP 命令路径和执行权限在不同环境差异极大
本地能跑的 php 命令,在 CI、Windows 或容器里大概率失效。根本原因不是 Composer,是 shell 解析规则和 PATH 不一致。
-
./vendor/bin/phpunit在 Windows 下常报错:去掉./前缀,直接写vendor/bin/phpunit -
sh: php: not found:改用全路径,如/usr/bin/php vendor/bin/phpunit;先运行which php查准路径 - 推荐用
vendor/bin/phpunit自身带 shebang 的可执行文件,比裸写php更可靠 - 避免在 script 中写
php -f ./some.php——-f不必要,且./在某些 shell 下反而引发解析异常
脚本退出码必须非零,否则 Composer 认为成功
Composer 判断脚本成败,只看子进程的 exit code。只输出错误信息、不 exit(1) 或抛异常,等于没报错。
- PHP 脚本中检测失败后,必须显式
exit(1);光echo "fail"+ 无退出 = Composer 认为成功 - 在 Composer 脚本类方法中,推荐抛异常(如
throw new RuntimeException("xxx")),Composer 会自动捕获并转为错误退出 - Shell 脚本里也要注意:最后一条命令失败但没
set -e或显式exit 1,也会被忽略
最常被忽略的一点:脚本执行时的当前工作目录(cwd)不总是项目根目录。某些 CI 环境或 IDE 插件会覆盖它,导致相对路径失效——别假设 ./ 永远指向你认为的位置。

















