composer脚本钩子仅支持预定义事件名,如①pre-install-cmd、②post-install-cmd、③pre-update-cmd、④post-update-cmd、⑤pre-autoload-dump、⑥post-autoload-dump;不支持自定义事件名,且必须严格匹配大小写与短横线格式,缺“-cmd”后缀或拼写错误均无效。

Composer脚本钩子能用哪些事件?
Composer的scripts支持预置事件名,不是随便起名就能触发。真正可用的生命周期钩子只有这些:
-
pre-install-cmd、post-install-cmd -
pre-update-cmd、post-update-cmd -
pre-autoload-dump、post-autoload-dump -
pre-dump-autoload(别名,等价于上一条)
注意:pre-require或post-composer-run这类名字是无效的,不会被识别。官方文档里列全了,但容易漏看cmd后缀——少写它就完全不执行。
怎么在post-install-cmd里发Slack通知?
核心是用curl发HTTP POST请求到Webhook地址,但得处理好退出码和错误捕获,否则一次失败会让整个composer install中断。
{
"scripts": {
"post-install-cmd": [
"curl -X POST -H 'Content-type: application/json' --data '{\"text\":\"✅ Composer install done on $(hostname)\"}' https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXX || true"
]
}
}
要点:
-
|| true必须加,否则curl失败(比如网络不通、URL写错)会导致composer install报错退出 - Slack Webhook返回400时body里有具体错误,但
curl默认不输出,调试时可加-v或把响应重定向到日志文件 -
钉钉格式不同,需用
\"msgtype\":\"text\",\"text\":{\"content\":\"...\"}结构,且必须带timestamp和sign(如需签名验证)
为什么post-update-cmd有时不触发?
常见原因有三个:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 当前目录下没有
composer.json,Composer会向上查找,但钩子只在找到的那个composer.json里定义才生效 - 运行的是
composer update vendor/package这种限定包更新,此时post-update-cmd仍会触发;但若用了--no-scripts参数,所有钩子都被跳过 - 脚本里调用了
php或sh命令却没加解释器路径,比如写"php notify.php"在某些Docker镜像里会因PATH缺失而失败,建议用"./notify.php"并确保文件有+x权限
用PHP脚本发通知比一行curl更可靠吗?
是的,尤其涉及钉钉签名、环境变量读取、多步骤状态组装时。比如钉钉要求的sign必须用HMAC-SHA256算出,shell里太难维护。
示例notify.php片段:
<?php $webhook = $_SERVER['DINGTALK_WEBHOOK'] ?? '';
$secret = $_SERVER['DINGTALK_SECRET'] ?? '';
if (!$webhook || !$secret) exit(0);
<p>$ts = time() * 1000;
$sign = base64_encode(hash_hmac('sha256', "$ts\n$secret", $secret, true));
$data = json_encode([
'msgtype' => 'text',
'text' => ['content' => "? Composer " . ($_SERVER['COMPOSER_EVENT'] ?? 'unknown')],
'timestamp' => $ts,
'sign' => $sign
]);<p>file_get_contents($webhook, false, stream_context_create([
'http' => ['method'=>'POST','header'=>"Content-type: application/json\r\n",'content'=>$data]
]));</p>
关键点:
- 依赖
COMPOSER_EVENT环境变量区分是install还是update,Composer自动注入 - 不要echo任何内容,否则可能污染Composer输出
- 如果用
exec()调curl,记得转义单双引号,不如直接用file_get_contents干净
有些团队把通知逻辑封装成独立Composer插件,但小项目真没必要——脚本够用,加个.gitignore忽略notify.php里的密钥变量就行。真正容易被忽略的是:Webhook URL和密钥绝不能硬编码进composer.json,必须走环境变量。










