pre-autoload-dump钩子在composer install/update执行到生成自动加载文件前触发,此时vendor/autoload.php尚未生成,仅支持纯文件操作;需在composer.json的scripts中注册,不响应dump-autoload命令。

pre-autoload-dump 钩子到底在什么时候触发
它在 composer install 或 composer update 执行到「生成自动加载文件」之前运行,但此时 vendor/autoload.php 还没生成,所有依赖包的类也尚未可加载。这意味着你不能在钩子里直接 new SomePackageClass(),也不能依赖 autoload 下的任何映射。
常见错误现象:Class not found、require_once failed,本质是误以为钩子执行时环境已就绪。
- 只适合做纯文件操作:如生成 stub 文件、修改
composer.json中的 autoload 配置、清理临时目录 - 不能调用第三方包函数,也不能依赖
vendor/autoload.php - 若需加载自定义逻辑,必须用
require 'path/to/your/script.php'显式引入(且该脚本不能依赖未安装的包)
怎么注册 pre-autoload-dump 脚本
在 composer.json 的 "scripts" 段里加一条键为 "pre-autoload-dump" 的命令即可,值可以是 PHP 脚本路径或内联命令:
"scripts": {
"pre-autoload-dump": [
"@php scripts/generate-stub.php",
"echo 'Autoload about to be dumped...'"
]
}
注意点:
- 数组形式支持多条命令,按顺序执行;字符串形式只支持单条
- 脚本路径是相对于项目根目录的,不是
vendor/bin - 如果用
@php,Composer 会自动使用当前运行的 PHP 可执行文件,避免硬编码/usr/bin/php - 不推荐写 shell 命令(如
cp、sed),Windows 兼容性差;优先用 PHP 脚本
PHP 脚本里能安全做什么
脚本本身由 Composer 启动,传入两个参数:$argv[1] 是事件名(pre-autoload-dump),$argv[2] 是 Composer\Script\Event 对象 —— 你可以从中拿到 getComposer() 和 getIO()。
典型可用操作:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 读取并修改当前项目的
composer.json(用json_decode(file_get_contents('composer.json'))+file_put_contents) - 生成供后续 autoload 使用的 classmap stub(比如把
resources/stubs/*.php复制到vendor/composer/下某处) - 检查某些目录是否存在,不存在则创建(
mkdir -p类逻辑) - 向
stdout输出提示(用$event->getIO()->write()更规范)
别碰的事:require 'vendor/autoload.php'、class_exists('Some\Package\Class')、调用 composer dump-autoload 自身(会递归触发)。
为什么有时候钩子根本不执行
最常见原因是:你运行的是 composer dump-autoload,而不是 install 或 update。这个钩子**不会**在手动执行 dump-autoload 时触发 —— 它只属于安装/更新流程的前置环节。
其他可能原因:
-
composer.json格式错误,导致 Composer 解析失败(检查composer validate输出) - 脚本返回非零退出码(比如 PHP 语法错误、
exit(1)),Composer 会中断整个流程并跳过 autoload 生成 - 用了
"scripts": { "pre-autoload-dump": "xxx" }但没加--no-scripts,却误以为被禁用了(其实默认就是启用的)
调试建议:在脚本开头加 file_put_contents('hook-ran.log', date('c')."\n", FILE_APPEND);,确认是否真没跑,还是跑完就报错了。
真正难处理的是跨平台路径拼接和 JSON 写入时的权限问题 —— 尤其在 CI 环境里,composer.json 可能是只读的,或者 vendor/ 目录被挂载为不可写。










