post-install-cmd 是 Composer 的脚本事件钩子,非可执行命令,仅在 composer install 成功后自动触发;需在 composer.json 的 scripts 下以数组形式配置,不支持传参,常见失效原因为 vendor 存在未变更或启用 --no-scripts。

直接说结论: post-install-cmd 不是命令,而是 Composer 的一个脚本事件钩子,它会在 composer install 成功执行完依赖安装后自动触发——但默认不干任何事,得你自己配。
post-install-cmd 是什么,不是什么
它属于 Composer 的 scripts 机制,本质是事件名,不是可直接敲的命令。你不会在终端里输入 composer post-install-cmd,也不会在命令行单独运行它。它只在 composer install 流程末尾被内部调用一次(前提是没出错且没加 --no-scripts)。
常见错误现象:Script xxx handling the post-install-cmd event returned with error code 1 —— 这说明你配了脚本,但它执行失败了,而 Composer 默认会中止整个流程。
- 它和
post-update-cmd是两套独立事件,install和update触发不同 - 它不会在
composer require或composer remove中触发(除非这些命令底层调用了install) - 它不支持传参,不能像 shell 脚本那样接收
$1 $2;参数得硬编码或靠环境变量
怎么在 composer.json 里配 post-install-cmd
写法很简单,但位置和格式容易错。必须放在 composer.json 的顶层 scripts 字段下,值是一个字符串数组(每个元素是一条要执行的命令)。
示例(清缓存 + 生成 autoload):
{
"scripts": {
"post-install-cmd": [
"@php artisan clear-compiled",
"@php artisan optimize"
]
}
}
- 数组里每项都会顺序执行;任意一项失败,后续就停,整个
composer install报错退出 - 以
@开头的(如@php)会被 Composer 当作内置命令解析,不是 shell 别名;@php等价于当前 PHP 可执行文件路径 - 普通命令(如
npm run build)要求系统 PATH 里有对应二进制,且项目根目录是工作目录 - 别写成字符串单值(
"post-install-cmd": "php foo.php"),Composer 5.6+ 要求必须是数组,否则静默忽略
为什么 post-install-cmd 有时不执行
最常踩的坑是:明明写了,却没看到日志、也没效果。原因往往不在脚本本身,而在触发条件没满足。
-
composer install已有vendor/且composer.lock没变 → Composer 走“跳过安装”逻辑,连post-install-cmd都不触发(它只在真正安装/解包后跑) - 用了
--no-scripts或COMPOSER_NO_INTERACTION=1环境变量 → 脚本被强制禁用 - 脚本里用了相对路径(比如
./bin/build.sh),但当前工作目录不是项目根 → 找不到文件 - PHP 版本不兼容:比如脚本里用了
match表达式,但 Composer 运行时 PHP 是 7.4 → 直接 Parse Error,报错信息可能藏在 verbose 日志里
和 post-autoload-dump 有什么区别
这两个钩子经常一起出现,但职责完全不同:post-install-cmd 关注“装完依赖后该做什么”,post-autoload-dump 关注“类加载器重生成后该做什么”。后者更轻量、更稳定。
-
post-autoload-dump在每次autoload.php重建时都触发(包括install、update、甚至dump-autoload命令) - 如果你只是想确保某些类映射更新后做点事(比如扫描注解、生成代理类),优先用
post-autoload-dump,它更精准、更少误触发 -
post-install-cmd更适合一次性动作:比如初始化配置文件、检查扩展是否启用、拉取前端依赖(npm ci)等依赖已就位后的操作
真正麻烦的是跨平台兼容性——比如你在 macOS 写了个 post-install-cmd 调用 sed -i '',到 Linux 就挂;或者用 php -S 启本地服务,CI 环境根本没开端口权限。这些细节不写进脚本逻辑里,光靠文档很难覆盖全。











