post-install-cmd是唯一标准事件,其他写法均无效;90%不执行因scripts未置根级、键名非全小写短横线“post-install-cmd”或值json格式错误;其仅在vendor为空或composer.lock不存在/过期时触发。

post-install-cmd 是唯一能“在安装后自动运行”的标准事件,其他写法如 PostInstall、post_install_cmd、after-install 全都不生效。
为什么 post-install-cmd 没反应?先查这三处
脚本不执行,90% 是配置位置或命名错,不是环境问题。
-
scripts字段必须在composer.json的**根层级**,不能嵌在extra、autoload或子包里 - 键名必须严格是
"post-install-cmd"(全小写、短横线、带-cmd后缀),拼错一个字符就静默失效 - 值必须是合法 JSON:字符串要加双引号,数组要方括号包裹,空格和逗号不能少
post-install-cmd 和 post-update-cmd 到底什么时候触发?
它们的触发逻辑不是“装了包就跑”,而是由 composer.lock 状态决定的:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
-
post-install-cmd:仅当vendor/为空或composer.lock不存在/过期时,composer install才会真正执行安装流程,并触发该事件 -
post-update-cmd:只要composer update运行且依赖有变更(哪怕只改了一个版本号),就一定触发 - 想“每次
install都执行”?别只靠post-install-cmd—— CI 流水线里常删掉vendor/和composer.lock再重装,这时它才生效;更稳的方式是同时注册"post-update-cmd": ["@post-install-cmd"]
CI/CD 里脚本被跳过?大概率是 --no-scripts
几乎所有托管平台(GitHub Actions、GitLab CI、Laravel Forge)默认加了 --no-scripts 参数来提速,你的 post-install-cmd 就直接被跳过了。
- 检查部署命令是否含
--no-scripts或-n,删掉它,或显式加--scripts - Docker 构建中常见写法:
composer install --no-interaction --no-scripts→ 改成composer install --no-interaction --scripts - 如果脚本里用了开发依赖(如
phpunit),而部署时加了--no-dev,那这些命令会报“command not found”——把关键逻辑拆成独立脚本名(如"deploy:clear"),再用composer run-script deploy:clear --no-dev显式调用
脚本里执行命令,路径和权限最容易翻车
当前工作目录确实是项目根目录,但 PHP CLI 配置、用户权限、环境变量可能和 Web 服务不一致,导致 php artisan 或 chmod 失败。
- 别写
php artisan cache:clear,改用php ./artisan cache:clear(开头加./锚定路径) - 涉及文件操作(如复制
.env.example),用getcwd()获取根路径:copy(getcwd() . '/.env.example', getcwd() . '/.env'); - Linux 权限问题高频发生:脚本由部署用户执行,但 Web 服务器用的是
www-data或nginx用户。避免在脚本里硬写chmod -R 755 storage/,改用chown -R www-data:www-data storage/(需部署用户有 sudo 权限) - Windows 下别用
rm -rf或cp,统一用 PHP 实现或 cross-env 包封装
最常被忽略的一点:post-install-cmd 不是部署钩子,它在你本地 composer install 时也会跑 —— 如果里面写了 php artisan migrate --force,协作开发时队友一装依赖,数据库就被清空了。










