pre-update-cmd 是 Composer 在执行 composer update 前触发的生命周期钩子,用于环境检查与风险提示;它不触发于 install,不可依赖 vendor/autoload.php,无法获取待更新包列表,失败则中止更新。

pre-update-cmd 不是命令,而是 Composer 的一个生命周期事件钩子。它在 composer update 执行前触发,但此时依赖尚未下载、vendor/ 未变更、composer.lock 也还没重写 —— 它是你做“更新前干预”的最后机会。
pre-update-cmd 触发时机与限制
这个钩子只在显式运行 composer update(或带参数如 composer update monolog/monolog)时触发,composer install 不会触发它。关键限制有三点:
- 不能依赖
vendor/autoload.php—— 此时vendor/可能仍是旧状态,甚至部分包已被删但未重装 - 无法读取将要更新的包列表(
$event->getOperationList()在pre-update-cmd中不可用;只有post-package-*类钩子才暴露具体包操作) - 若脚本失败(exit code ≠ 0),整个
composer update会中止,这是它作为“守门人”的核心价值
常见用途:环境检查与风险提示
它不适合生成代码或修改 autoload,而适合守住安全边界。典型场景包括:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 检查 PHP 版本是否满足即将拉入的新依赖要求(例如某包将 require php >= 8.2,而当前是 8.1)
- 确认 Git 工作区干净:
git status --porcelain非空则 abort - 读取
composer.json中自定义字段(如"require-dev": {"phpunit/phpunit": "^10"})并校验本地 PHPUnit 是否兼容 - 输出警告:“检测到 dev-master 依赖,建议改用稳定版本”——用
$io->warning()而非echo,保证颜色和格式统一
配置写法与执行陷阱
必须写在 composer.json 的 scripts 下,值可以是字符串或数组:
{
"scripts": {
"pre-update-cmd": [
"@php -r "if (version_compare(PHP_VERSION, '8.2.0', '<')) { exit(1); }"",
"My\Check::warnDevMaster"
]
}
}
注意几个易错点:
- 不要在数组里混用 shell 命令和 PHP 方法调用 —— Composer 会按顺序执行,但错误处理不一致;推荐全用 PHP 类方法,便于调试和复用
-
@php是别名语法,等价于php,但它会继承 Composer 当前使用的 PHP 可执行路径,避免硬编码/usr/bin/php导致多版本冲突 - 类方法必须是
public static,且接收单个ComposerScriptEvent参数;若没声明命名空间或没加use,会直接 fatal error - 不要在
pre-update-cmd里调用composer dump-autoload或修改composer.lock—— 这些操作应留给后续阶段
为什么不用 pre-install-cmd 替代?
因为 pre-install-cmd 在 composer install 前触发,而 install 通常用于部署或 CI,依赖已由 lock 锁死,基本无动态风险;pre-update-cmd 才是开发期真正需要“审慎放行”的环节。两者语义不同,混用会导致逻辑错位——比如你在 pre-install-cmd 里检查 PHP 版本,却漏掉了 update 引入更高版本依赖的风险。

















