pre-install-cmd不是Composer原生事件,脚本不会执行;唯一可靠安装前钩子是pre-autoload-dump,它在锁文件校验通过、依赖解析完成、vendor尚未写入时触发,支持轻量PHP环境检查。

pre-install-cmd 不是 Composer 原生支持的事件,写它不会报错,但脚本根本不会执行——这是绝大多数人配置失败的第一原因。
composer.json 里写 pre-install-cmd 为什么没反应
Composer 官方事件列表中压根没有 pre-install-cmd。你看到的“教程”大概率混淆了旧插件、第三方扩展,或是手误拼错。实际可用的、最接近“安装前”语义的原生事件只有一个:pre-autoload-dump。
-
pre-autoload-dump在composer install和composer update中都会触发,且时机可靠:锁文件校验通过、依赖解析完成、vendor/尚未写入 —— 正是你做环境检查的黄金窗口 -
pre-update-cmd只在composer update前跑,对install完全无效 -
post-root-package-install名字带“install”,但它是根包安装“后”才触发,此时vendor/已部分生成,不能算“前” - 任何形如
before-install、on-pre-install、preInstall的写法,全部被忽略,不警告也不报错
用 pre-autoload-dump 做 PHP 环境检查的实操要点
它必须注册在 scripts 段里,且命令需能在无 autoload 环境下运行(因为此时 vendor/autoload.php 还没生成)。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 优先用
@php -r写轻量检查,比如:"@php -r \"if (!extension_loaded('gd')) { echo 'GD extension missing'; exit(1); }\"" - 避免调用尚未加载的类(如
MyChecker::validate()),除非该类已通过autoload.files静态引入 - 脚本返回非 0 状态码(如
exit(1))会中止整个composer install,这是合理拦截方式 - 别在脚本里读
vendor/下的文件或 require 第三方库 —— 此时它们还不存在
CI/CD 中 pre-autoload-dump 不触发的常见原因
不是钩子失效,而是执行上下文被限制了。
- CI 默认加了
--no-scripts,得显式关掉:composer install --no-scripts=false(新版 Composer)或composer install --no-dev --no-interaction(旧版兼容写法) - shallow clone 导致
.git缺失,某些自定义逻辑误判为非开发环境而跳过 —— 加--no-interaction并验证git rev-parse --is-inside-work-tree结果 - vendor/ 已存在且
composer.lock未变,Composer 可能跳过 autoloader 重建 —— 此时pre-autoload-dump不会触发;如需强制,加--force-autoloader - 加
-v参数运行:composer install -v,观察输出里是否出现Executing script行,这是唯一可信的验证方式
真正要拦住首次部署的环境问题,靠名字像的钩子没用;pre-autoload-dump 是唯一兼顾时机、兼容性和可验证性的选择,但它要求你放弃“先装包再检查”的惯性思维——检查动作必须能脱离 vendor/ 独立运行。










