post-update-cmd是首选事件,因它在每次composer update成功后稳定触发,包括首次安装后的第一次update;而post-install-cmd在首次install时因vendor/autoload.php不存在而不运行,易漏初始化逻辑。

直接用 post-update-cmd,但必须写成可执行的 PHP 脚本文件或带完整路径的命令,不能只写函数名或裸类名。
为什么 post-update-cmd 是首选事件
它在每次 composer update 成功后稳定触发,包括首次安装依赖后的第一次 update;而 post-install-cmd 在首次 composer install 时不会运行(因为 vendor/autoload.php 还不存在),容易漏掉关键初始化逻辑。
-
post-update-cmd不区分“是否新增包”,只要锁文件变动、autoload 重建完成就触发 - 如果你的脚本需要读取刚更新的包信息(比如检查某个包版本),只有这个事件配合 PHP 类写法才能拿到
$event->getComposer() - CI/CD 中频繁执行
composer update,用它最可控
怎么写一个安全可用的 PHP 脚本文件
别把逻辑塞进 composer.json 里一行行写,单独建文件更易维护、调试、加日志。假设你新建 scripts/post-update.php:
<?php // scripts/post-update.php
if (!file_exists(__DIR__ . '/../vendor/autoload.php')) {
exit("Autoloader not found. Run 'composer install' first.
");
}
require __DIR__ . '/../vendor/autoload.php';
echo "Running post-update tasks...
";
// 示例:清理缓存、生成配置、检查迁移文件
exec('php artisan config:clear 2>/dev/null');
exec('php artisan migrate:status --no-interaction 2>/dev/null');
// 注意:不要在这里调用 exit() 或 die(),会中断 Composer 流程
然后在 composer.json 里引用它:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
"scripts": {
"post-update-cmd": [
"php scripts/post-update.php"
]
}
- 脚本开头必须显式
requireautoload,否则类找不到 - 用
exec()或shell_exec()调用框架命令时,确保工作目录是项目根目录(getcwd()通常就是) - Linux/macOS 下记得给脚本加执行权限:
chmod +x scripts/post-update.php - Windows 用户可忽略权限,但别加
#!/usr/bin/env php—— Composer 不走 shebang
常见错误:命令能跑,但没效果或报错
现象包括:提示 Class not found、Command not found、脚本静默退出、迁移没执行。
- 写了
"MyScript::run"却没在composer.json的autoload里声明对应命名空间 → 补上"psr-4": {"My\": "scripts/"}并运行composer dump-autoload - 用了
php artisan但当前环境没加载 Laravel 核心 → 改用exec('cd .. && php artisan ...')或确认app()可用再调用 - 误以为
@php能自动引入项目 autoload → 它只是快捷方式,等价于系统php命令,不带任何上下文 - 脚本里用了相对路径如
./config/app.php→ 改用__DIR__ . '/../config/app.php',因为 Composer 不保证当前工作目录是项目根目录
要不要在生产环境自动跑数据库迁移
不建议。自动迁移本质是把部署决策权交给了 composer update,而后者可能在开发机、CI、甚至本地 git pull 后误触发。
- 如果真要支持,至少加环境判断:
if (getenv('APP_ENV') === 'local') { Artisan::call('migrate'); } - 更稳妥的做法:把迁移拆到独立脚本,用
composer run-script deploy-migrate显式触发 - 所有涉及数据库变更的操作,都不该依赖 Composer 钩子作为唯一入口 —— 它不是部署工具,只是辅助手段
最常被忽略的一点:脚本里调用的命令(比如 php artisan)是否真的存在于当前环境?CI 镜像里没装 Laravel,或者用了 Docker 但没挂载 vendor,都会让钩子看起来“运行了”实则什么都没做。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










