composer 的 scripts 是声明式绑定命令到生命周期事件的键值表,不解析逻辑、不支持条件循环,所有命令在项目根目录执行,可用 @ 调用其他 script,数组形式顺序执行且失败中断。

scripts 是什么?不是脚本文件,而是事件钩子映射表
Composer 的 scripts 不是你写个 .sh 或 .php 文件然后执行它——它是把命令“声明式绑定”到生命周期事件或自定义名上的一张键值表。你改了 composer.json 里的 scripts,只是告诉 Composer:“等你做完 install,就顺手跑一下这个命令”。它本身不解析逻辑、不支持 if 或 for,也不切换工作目录。
- 所有命令默认在项目根目录(
$PWD)下执行,没法指定cwd -
@xxx表示调用另一个 script,比如@test,可嵌套但不能递归死循环 - 数组形式
["cmd1", "cmd2"]是顺序执行,失败会中断(除非加|| true) - Windows 下别用反斜杠路径,
vendorinphpunit在某些旧版 Composer 里直接报错,一律用正斜杠vendor/bin/phpunit
怎么配一个能跑的 test 脚本?优先走 vendor/bin
想运行 PHPUnit,别依赖全局安装的 phpunit,因为版本、PHP 扩展、INI 配置都可能不一致。直接指到项目本地的二进制文件最稳。
- 确保
phpunit.xml.dist存在且路径正确(常用位置:项目根目录) - 配置写成:
"test": "vendor/bin/phpunit --configuration phpunit.xml.dist" - 运行时传参要用双横线:
composer run test -- --filter=MyTest,中间的--是分隔符,后面内容原样拼到命令末尾 - 如果要兼容 Windows + Linux,避免用
$@这类 shell 特性;想透传参数,老实用--+ 显式参数
post-install-cmd 自动清理怎么写才安全?
很多人想“装完包自动删缓存”,但直接写 rm -rf storage/cache 很危险:没判断目录是否存在、没考虑权限、不可重试、Windows 下直接挂掉。
本书图文并茂,详细讲解了使用LAMP(PHP)脚本语言开发动态Web程序的方法,如架设WAMP平台,安装与配置开源Moodle平台,PHP程序设计技术,开发用户注册与验证模块,架设LAMP平台。 本书适合计算机及其相关专业本、专科学生作为学习LAMP(PHP)程序设计或动态Web编程的教材使用,也适合对动态Web编程感兴趣的读者自觉使用,对LAMP(PHP)程序设计人员也具有一定的参考价值。
- 推荐用幂等的内联 PHP 判断:
"@php -r "if (is_dir('storage/cache')) { array_map('unlink', glob('storage/cache/*')); echo '✓ 清理完成\n'; } else { echo '⚠ cache 目录不存在\n'; }"" - 更复杂的逻辑(比如扫描符号链接、校验哈希)应抽成 PHP 类方法,如
App\Scripts\Cleanup::run,并确保该类已注册进autoload - 不要在
post-install-cmd里执行耗时操作(如下载远程资源),它会阻塞 install 流程,CI 环境容易超时 - 注意:首次
create-project后触发的是post-create-project-cmd,不是post-install-cmd,别配错
调试 scripts 报错为什么总看到 “Script xxx returned error code 1”?
Composer 默认只甩出退出码,不打印 stderr,根本不知道哪条命令崩了、为什么崩。尤其当你用数组写多条命令,又没加 -v,等于盲跑。
- 加
-v(verbose)是唯一靠谱办法:composer run test -v,能看到每条命令实际执行的完整字符串和输出 - Shell 命令里别省略
set -e或等效逻辑,否则前一条失败,后一条还继续跑,掩盖真实问题 - PHP 回调方法必须接收
ComposerScriptEvent参数,否则调用时会报Missing argument错误 - 环境变量可用,比如
$COMPOSER_HOME、$PWD,但$0没意义——这里根本没有“当前脚本文件”
事情说清了就结束。最常被忽略的其实是“scripts 不是万能胶水”,它适合轻量触发,真要处理文件树、网络请求、并发任务,还是得交给 Makefile、npm script 或专用 CLI 工具。别硬塞。









