composer没有可靠的“每包安装后执行”钩子,post-package-install是experimental内部事件,不被scripts支持;需写插件监听installerevents::post_package_install,或改用稳定的post-autoload-dump。

Composer 没有“每个包安装完就执行一次”的可靠钩子——post-package-install 不是你想要的,它不传包信息、不保证触发、官方标记为 experimental,2026 年仍不建议依赖。
为什么 post-package-install 脚本根本跑不起来
常见错误现象:composer install 完了脚本没运行;或运行了但 $event->getOperation() 返回 null;更糟的是你以为能拿到 monolog/monolog 的版本和路径,实际只能拿到模糊的 InstallOperation 实例,且仅在部分 update 场景下可用。
根本原因:
-
post-package-install是 Composer 内部事件名,不是scripts字段支持的生命周期事件 —— 它压根不会被composer.json里的scripts解析 - 它只在
install/update整体流程结束时触发一次,不区分包,也不保证每次composer require foo/bar都走这一趟(缓存命中就跳过) - 官方文档明确写“experimental”,未来可能移除
真正能捕获“某个包刚装进 vendor”时机的方法
必须写 Composer 插件,监听底层 InstallerEvents::POST_PACKAGE_INSTALL 事件,而不是配 scripts。
关键实操点:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 插件类需实现
Composer\Plugin\PluginInterface和Composer\EventDispatcher\EventSubscriberInterface - 订阅事件必须用常量
Composer\Installer\InstallerEvents::POST_PACKAGE_INSTALL,不能写字符串"post-package-install" - 在回调里调用
$event->getOperation()->getPackage()才能稳定拿到PackageInterface实例,含包名、版本、源类型等完整信息 - 插件需声明
"type": "composer-plugin",并被根项目require(不能只放require-dev)
更简单、更稳定的替代方案:用 scripts + post-autoload-dump
如果你只是想在依赖装完后“做点事”,比如生成配置、清理缓存、注册 bin 文件,post-autoload-dump 是目前最稳的选择 —— 它每次 autoloader 重建都触发,时机比 post-install-cmd 更确定,且一定带 $event->getDumpAutoloader()。
配置方式(写在根目录 composer.json 的顶层 scripts 字段):
"scripts": {
"post-autoload-dump": [
"@php scripts/after-install.php"
]
}
注意:
-
post-autoload-dump属于官方支持的脚本事件,不是 experimental - 它会在
install、update、甚至手动dump-autoload时触发,适合幂等操作 - 不要指望它告诉你“哪个包变了”——它只反映 autoloader 状态,不提供包粒度上下文
复杂点在于:你要处理单个包的安装后逻辑,就必须写插件;如果只是项目级部署动作,post-autoload-dump 或组合 post-install-cmd + post-update-cmd 就够用。别在 scripts 里硬塞 post-package-install,它永远不会执行。










