Composer脚本必须定义在composer.json顶层"scripts"键下,为键值对结构:键是命令名,值支持字符串命令、数组或多条命令、PHP回调(需public static且类已自动加载)。

Composer脚本怎么定义在composer.json里
Composer脚本本质是键值对,写在composer.json的"scripts"字段下,值可以是命令字符串、数组(多条命令)、或指向PHP方法的回调(需类+方法名)。它不支持Shell语法扩展(比如&&、管道),也不自动加载项目类——除非你显式require/autoload。
常见错误:把phpunit直接写成"phpunit",结果报Command "phpunit" is not defined。原因是你没加vendor/bin/前缀,或没声明"bin-dir";更稳妥写法是"vendor/bin/phpunit"或用@php vendor/bin/phpunit确保调用当前PHP二进制。
-
"test":"@php vendor/bin/phpunit"—— 显式指定PHP可执行文件,避免CLI版本与项目要求不一致 -
"post-install-cmd":["@php scripts/install-hook.php"]—— PHP脚本必须有可执行权限且首行含#!/usr/bin/env php,否则会提示Permission denied - 避免在脚本里写
cd切换目录,Composer执行时工作目录就是项目根目录,硬切反而容易路径错乱
怎么让自定义脚本接收参数并传给PHP函数
Composer原生不解析脚本参数,composer run-script xxx -- --flag value中的--之后内容会被拼成一个字符串,原样传给PHP回调的$args参数(类型为array,每个元素是空格分隔后的子串)。
例如定义:"scripts": {"build": "MyBuild::run"},对应PHP类:
class MyBuild { public static function run($event) { $args = $event->getArguments(); // 如执行 composer build -- --env prod --tag v1.2,则 $args == ['--env', 'prod', '--tag', 'v1.2'] }}注意:Composer不会帮你解析--env=prod这种等号形式,必须写成--env prod;也别指望它自动转成$_SERVER或$argv,全靠你自己处理。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 推荐用
symfony/console封装复杂参数逻辑,但记得在require-dev里声明,否则生产环境运行可能失败 - 如果脚本只用于开发,加
"dev": true到脚本定义里(如"build": {"dev": true, "callable": ["MyBuild", "run"]}),这样composer install --no-dev时会跳过它 - 不要在回调里抛出未捕获异常,否则Composer会打印堆栈并退出,掩盖真实错误原因;建议用
$event->addOutput()输出提示再exit(1)
为什么post-autoload-dump里不能用new \SomeClass()
因为这个事件触发时,vendor/autoload.php刚生成完但尚未加载,ClassLoader实例还没初始化,所有use和new都会报Class not found。你只能操作文件系统、读写JSON、调用exec()或shell_exec()等不依赖自动加载的逻辑。
典型场景是生成IDE辅助文件(如.phpstorm.meta.php)或检查PSR规范,但凡涉及项目代码,就得绕开:
- 改用
post-install-cmd或post-update-cmd,此时autoload.php已可用 - 如果非要在
post-autoload-dump里用类,得手动require_once 'vendor/autoload.php',但风险高——可能引发重复注册或加载顺序问题 - 别在该钩子里执行
composer dump-autoload,会触发无限递归
运行脚本时提示Script ... handling the ... event returned with error code 1
这是Composer的通用错误包装,实际原因藏在上一行输出里。最常被忽略的是:脚本进程退出码非0即报此错,哪怕只是echo "done"; exit(1);也会触发。
排查重点不是看这句提示,而是盯紧它上面的原始输出:
- PHP语法错误?检查
php -l script.php是否通过 - 权限问题?Linux/macOS下确认
script.php有+x权限,Windows则必须用.bat或.cmd包装 - 路径错误?
__DIR__在Composer脚本中指向vendor/composer/目录,不是项目根目录;要用getcwd()或dirname(__DIR__, 2)回溯 - 内存溢出?Composer默认限制1.5G,大项目跑静态分析可能OOM,加
php -d memory_limit=-1前缀临时绕过
复杂点在于:同一个脚本,在composer install和composer run-script中执行环境不同(前者触发钩子链,后者单次调用),某些变量(如$event->getComposer())在后者里为null。这点容易被忽略,导致本地测试通过,CI里却空指针。

















