composer只识别post-install-cmd(全小写、短横线),非postinstall或post_install_cmd;该事件仅在composer.lock不存在或过期时触发,需配合post-update-cmd或改用post-autoload-dump实现每次install执行。

PostInstall 脚本根本不存在,composer 只认 post-install-cmd
Composer 没有 PostInstall 这个事件名,大小写、拼写、下划线全错——它只识别标准事件名 post-install-cmd(全小写、短横线)。写成 PostInstall 或 post_install_cmd 都不会触发。
常见错误现象:composer install 执行完脚本完全没反应,composer run-script 却能手动跑通——大概率是事件名写错了。
-
post-install-cmd:仅在composer install且锁文件(composer.lock)**不存在或过期**时触发 -
post-update-cmd:composer update时触发,也覆盖部分 install 场景(比如 lock 文件存在但依赖有变更) - 想“每次 install 都执行”,得同时注册两个事件,或统一用
post-autoload-dump(更稳定,但时机稍晚)
怎么在 composer.json 里正确配置自动脚本
脚本必须放在 "scripts" 字段下,键为事件名,值为命令数组或字符串。别漏掉外层 "scripts" 包裹。
示例(修正后的最小可用配置):
{
"scripts": {
"post-install-cmd": [
"@php -r "echo '✅ Install done\n';"",
"php artisan optimize:clear"
],
"post-update-cmd": ["@post-install-cmd"]
}
}
- 数组形式支持多条命令,按顺序执行;字符串形式只支持单条
-
@xxx是引用其他脚本的语法,不是注释,@post-install-cmd会复用上面定义的全部命令 - 如果命令含空格或特殊字符(如
php artisan migrate --force),建议整个命令用双引号包裹 - 避免在脚本里写
cd切目录——composer 执行脚本时工作目录就是项目根目录,硬切反而容易出路径错
为什么本地能跑,CI/CD 里不执行?
因为 composer install --no-scripts 是 CI 环境默认行为(为提速禁用脚本),你得显式加 --scripts 或删掉 --no-scripts。
- Docker 构建中常见:镜像里用了
composer install --no-interaction --no-scripts,脚本直接被跳过 - GitLab CI / GitHub Actions 中检查
composer install命令是否带--no-scripts或-n - 某些托管平台(如 Laravel Forge)部署时默认禁用脚本,需在部署脚本里补上
--scripts - 用
composer run-script post-install-cmd手动触发是临时验证手段,但不能替代事件绑定
post-install-cmd 不适合做耗时操作
这个钩子运行在依赖安装流程内,如果脚本卡住或失败(比如数据库连不上、前端构建超时),整个 composer install 就会中断,导致依赖没装完、autoload 没生成——项目直接变不可用。
- 别在
post-install-cmd里跑npm install、php artisan migrate或调外部 API - 适合做的事:清理缓存、生成静态配置文件、打印提示信息
- 真要跑迁移或构建,应该拆到独立部署步骤,和 composer 安装解耦
- 注意权限问题:Docker 或 CI 环境里 PHP 用户可能没权限写
storage/或bootstrap/cache/,脚本报错但不提示具体原因
事件名拼写、CI 默认禁用、脚本阻塞安装流程——这三个点踩中任一个,脚本就静默失效。没日志、没报错、也没回显,是最容易让人抓瞎的地方。










