post-install-cmd仅在真正重建vendor时触发,如首次克隆、删lock后重装或lock与composer.json冲突;vendor存在且lock未变则跳过,且必须严格命名、置于scripts顶层,CI中--no-scripts会禁用它。

post-install-cmd 为什么没执行
它根本不是“每次 composer install 都跑”,而是只在真正重建 vendor/ 时才触发:比如首次克隆、删了 composer.lock 后重装,或 composer.json 与 composer.lock 冲突导致依赖被重新解析。如果 vendor/ 已存在且 lock 没变,Composer 直接跳过安装流程,钩子就静默不启动。
常见误判点:
-
composer.json里没写"scripts"顶层字段,或写在了"extra"或"autoload"里 - 键名拼错:写成
post-install、post_install_cmd、PostInstallCmd—— 必须严格是post-install-cmd - CI 环境默认加了
--no-scripts,所有脚本都被禁用,包括这个钩子 - 本地已装过,想测试却没清
vendor/和composer.lock,结果什么都没发生
post-install-cmd 和 post-update-cmd 怎么选
别按字面理解“安装”和“更新”,关键看触发条件是否匹配你的部署场景:
-
post-install-cmd:适合 CI/CD 流水线拉完新代码后首次构建镜像、初始化环境(如生成配置、预热缓存) -
post-update-cmd:适合本地开发中改了依赖、运行composer update后同步状态(如迁移数据库、刷新注解) - 想统一行为?共用一个自定义脚本名,例如:
"post-install-cmd": ["@deploy:setup"]和"post-update-cmd": ["@deploy:setup"],再把具体逻辑写在"deploy:setup"里
注意:post-install-cmd 在 composer update 时不会触发;反过来,post-update-cmd 在首次 composer install 时也不会触发——它们互不替代,只响应各自命令的完成事件。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
钩子里调用 PHP 命令容易崩在哪
直接写 php artisan config:clear 是高危操作:CI 容器里可能没有 php 命令,或版本错乱(Composer 用的是 php8.2,系统 PATH 却指向 php7.4)。更糟的是权限和路径问题。
- 用
@php替代裸php:它复用当前 Composer 进程的 PHP 可执行路径,避免版本/ini 错乱 - 路径必须锚定:写
@php ${PWD}/artisan config:clear,而不是php artisan config:clear,防止工作目录意外变更 - 内存不够?加
-d memory_limit=-1:比如@php -d memory_limit=-1 ./artisan cache:warmup - 交互式命令要加
--no-interaction --force:否则php artisan migrate会卡在确认提示上 - 别假设
.git存在:CI 构建镜像常是 shallow clone,cp .git/hooks/*这类操作会直接失败
生产部署时怎么确保关键脚本一定跑
靠 post-install-cmd 在生产机上并不可靠:很多部署流程会加 --no-dev --optimize-autoloader,但忘了 --no-scripts 默认是开启的,或者脚本本身依赖 phpunit 这类 dev-only 工具,一执行就报错退出。
- 把真正关键的部署逻辑(如清缓存、写配置、设权限)拆成独立脚本名,例如
"deploy:setup" - 在 CI 脚本里显式调用:
composer run-script deploy:setup --no-dev,绕过钩子触发条件限制 - 敏感操作加兜底判断:比如在脚本开头加
if [ ! -d "storage" ]; then mkdir -p storage; fi,避免因目录缺失直接中断 - 权限问题高频发生:部署用户 ≠ Web 用户,
chmod -R 755 ${PWD}/storage得写全路径,且最好配合chown显式指定属主
最常被忽略的一点:钩子执行时的当前工作目录确实是项目根目录,但某些 Docker 挂载方式或 symlink 场景下,getcwd() 可能返回意外路径——所以任何涉及相对路径的操作,都建议用 ${PWD} 或 $(pwd) 显式锚定,别信“应该就在根目录”。

















