post-install-cmd 是 Composer 在首次执行 composer install(vendor/ 不存在或为空)时触发的脚本钩子,不用于 update;需在 composer.json 的 scripts 中定义,支持 shell 命令、PHP 回调或闭包,失败则中断安装,调试可用 -v 参数。

post-install-cmd 是什么,什么时候会触发
post-install-cmd 是 Composer 提供的脚本钩子(script hook),在执行 composer install 且检测到 vendor/ 不存在或为空时触发。它不会在 composer update 时运行——那是 post-update-cmd 的职责。
注意:如果项目已有 vendor/ 目录,再次运行 composer install 默认跳过安装,post-install-cmd 也不会执行。想强制触发,得加 --no-cache 或先删掉 vendor/ 和 composer.lock(不推荐后者)。
在 composer.json 中定义 post-install-cmd 脚本
直接在 composer.json 的 "scripts" 字段下添加即可。支持字符串命令、PHP 回调、闭包(需配合 Composer\Script\Event)。
- 执行 shell 命令(最常用):
"post-install-cmd": ["@php -r \"echo 'Installed!\\n';\"", "chmod +x bin/*"]
- 调用自定义 PHP 方法(需确保类已 autoload):
"post-install-cmd": ["MyVendor\\Scripts::onInstall"]
- 内联匿名函数(仅限 Composer 2.2+,且必须写成单行):
"post-install-cmd": ["php -r \"(new class{public function run($e){echo 'OK\\n';}})->run($argv[1]);\""]
多个命令用数组写法,按顺序执行;单个字符串会被当作 shell 执行(等价于 sh -c),但可读性差、易出错,不建议。
常见错误和兼容性陷阱
脚本失败会导致 composer install 整体退出(非静默忽略),所以务必测试容错性:
-
php artisan key:generate在 Laravel 项目中常被放进post-install-cmd,但如果.env不存在,它会报错中断——应改用php artisan key:generate --no-interaction || true或提前检查文件 - Windows 下路径分隔符和命令语法差异大,
chmod、rm -rf等 Unix 命令会失败,建议用跨平台工具如robloach/component-installer或封装成 PHP 脚本 - 脚本里访问
$event->getComposer()或$event->getIO()需要声明参数类型(PHP 8.0+ 类型声明严格),否则可能报ArgumentCountError - Composer 1.x 不支持
static function作为回调,必须用public static function
调试 post-install-cmd 脚本执行过程
加 -v 或 --verbose 参数看详细日志:
composer install -v。它会打印每条脚本的完整命令、返回码和标准输出。
临时禁用所有脚本可用:
composer install --no-scripts,用于排除是否是钩子本身导致安装失败。
若脚本依赖尚未安装的类(比如想在 post-install-cmd 里用 symfony/console),会因 autoloader 还没生成而 fatal error——此时只能用原生 PHP 或 shell 实现逻辑,或改用 post-autoload-dump(它在 autoloader 生成后触发)。
真正难搞的是环境变量和工作目录:Composer 执行脚本时,getcwd() 是项目根目录,但某些 shell 命令(如 npm run build)可能依赖 package.json 位置,务必确认相对路径正确;CI 环境中还要留意 HOME、PATH 是否被重置。










