post-install-cmd仅在真正安装依赖时触发,如首次克隆、删除composer.lock后重装或lock与composer.json冲突需重建时;若vendor存在且lock未变则跳过,不执行。

post-install-cmd 不是“每次 composer install 都会跑”的钩子,它只在真正发生依赖安装时触发——比如首次克隆、删了 composer.lock 后重装、或 lock 文件与 composer.json 冲突需重建时。
post-install-cmd 触发条件很具体
很多人配好了脚本却没反应,根本原因不是写错了命令,而是压根没满足触发前提:
- 项目已有
vendor/且composer.lock没变 → Composer 跳过安装流程,post-install-cmd不执行 -
composer install --no-scripts(CI 环境常默认启用)→ 所有脚本被静默禁用 -
composer.lock存在但内容过期(比如改了composer.json的 require 却没更新 lock)→ 此时 Composer 会先重生成 lock,再安装,post-install-cmd才会跑 - 事件名写成
PostInstall、post_install_cmd或post-install→ Composer 完全不识别,必须严格为post-install-cmd(全小写、短横线)
在 composer.json 中正确声明脚本
必须放在顶层 scripts 字段下,值必须是数组(5.6+ 强制要求),不能是单字符串:
{
"scripts": {
"post-install-cmd": [
"@php -r \"file_put_contents('runtime/.installed', date('c'));\"",
"php artisan config:clear",
"php bin/generate-config.php"
]
}
}
关键点:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 以
@php开头的命令会被 Composer 替换为当前 PHP 可执行路径,比硬写php更可靠 - 外部命令如
npm install要求系统 PATH 中存在npm,CI 镜像里得提前装 Node.js - PHP 脚本建议用
php -f script.php,不用./script.php(可能无执行权限) - 不要在脚本里用
__DIR__推导路径——Composer 是用proc_open启新进程,__DIR__指向的是 PHP 解释器位置,不是你的脚本目录
常见失败原因:权限、路径、时机
脚本报错或静默跳过,往往卡在这几个实际问题上:
-
sh: 1: npm: not found→ CI 容器没装 Node.js,不能只看本地有就认为线上也有 -
Permission denied: ./artisan→ Laravel 的artisan缺少可执行位,应改用php artisan - 相对路径失效(如
../config/app.php)→ 当前工作目录是composer.json所在目录,不是脚本所在目录;推荐用__DIR__ . '/vendor/autoload.php'显式引入自动加载 - 脚本里用了未启用的 PHP 扩展(如
mbstring),而容器里没装 → 运行直接崩,但 Composer 默认不报详细错误 - 想读
composer.json内容?别file_get_contents(__DIR__ . '/../composer.json')—— 改用ComposerInstalledVersions::getRawData()(v2+)更稳定
和 post-update-cmd、post-autoload-dump 的区别
这三个钩子时机不同,混用容易出问题:
-
post-install-cmd:只在composer install真正安装依赖后触发(适合部署初始化) -
post-update-cmd:在composer update和composer install --update时都稳定触发(更适合开发阶段同步变更) -
post-autoload-dump:每次自动生成 autoload 文件后都触发(包括 install/update),时机稍晚但更频繁(适合缓存清理、代理类生成)
真正难搞的不是怎么写,而是判断该用哪个钩子——尤其在 CI 流水线里,composer install 行为会因 vendor/ 和 lock 文件状态动态变化,不验证就假设“肯定执行”会踩坑。










