composer不执行迁移,真正执行的是php artisan migrate等命令;需在composer.json中用@php artisan migrate --force等无交互方式配置,确保autoload就位、路径可靠、php解释器明确。

Composer 本身不执行数据库迁移,它只负责调用你写的命令;真正干活的是 php artisan migrate、doctrine:migrations:migrate 或 vendor/bin/phinx migrate 这类工具。关键不是“能不能做”,而是命令能否在当前环境无交互、autoload 就位、配置可用地跑通。
composer.json 里怎么安全写迁移脚本
直接在 "scripts" 段加一条命令即可,但必须满足三个硬性条件:无交互、路径可靠、PHP 解释器明确。
-
--no-interaction或--force必须显式带上,否则 CI 或部署时会卡住等待输入 - 别写
php artisan migrate,要写@php artisan migrate --force——@php由 Composer 自动解析为当前 PHP 二进制路径,避免 Windows 下找不到 php 或 Linux 下版本错乱 - 如果项目不是 Laravel,默认不带
artisan,得换对应命令,比如 Symfony 用@php bin/console doctrine:migrations:migrate --no-interaction,Phinx 用@php vendor/bin/phinx migrate -e production - 环境变量如
DB_HOST不会自动从.env加载,需前置注入:APP_ENV=production @php artisan migrate --force
post-install-cmd 和 post-update-cmd 能否自动触发迁移
能,但仅限「依赖变更强相关」的轻量操作,且必须确保 autoload 已刷新、数据库连接可用。它不是部署编排工具,塞服务重启或权限修复只会让问题更难定位。
- 常见失败现象:
Class 'Illuminate\Support\Facades\Schema' not found——本质是post-update-cmd触发时autoload.php还没生成,迁移命令却已依赖 Facade 类 - 正确顺序应是:
post-autoload-dump钩子(Laravel 推荐)或手动在脚本里先跑composer dump-autoload,再调迁移 - 敏感操作如
migrate:fresh绝不能放进post-*钩子,测试环境重装依赖时可能误清生产库 - 钩子只在根项目执行,monorepo 中若各包有独立
composer.json,它们的post-*不会触发,统一迁移逻辑应收归根目录
为什么迁移总报 “Class not found” 或 “Base table not found”
这两类错误看起来像 autoload 或 SQL 问题,但根源常不在迁移命令本身,而在执行上下文是否就绪。
-
Class not found多半是 autoload 未更新:新写的 migration 类文件名格式不对(Laravel 要求YYYY_MM_DD_HHMMSS_create_posts_table.php),或类名与文件名不一致(应为CreatePostsTable),导致Finder扫不到 -
Base table not found: 1146往往是迁移执行顺序错乱:比如在up()里查了users表,但该表对应的 migration 文件时间戳更小、还没执行;检查doctrine_migration_versions表或 Laravel 的migrations表确认已执行序号 - Phinx 报
could not locate a config file:安装后必须手动运行vendor/bin/phinx init生成phinx.php,不能跳过 - Doctrine Migrations 不读
.env,得单独配doctrine-migrations.yml或用--configuration指定,URL 中密码含@或/必须 URL 编码(如pa%40ss%2Fword)
Monorepo 中迁移文件该怎么放
所有迁移文件必须统一放在 monorepo 根目录的 database/migrations(Laravel)或 migrations(Doctrine/Phinx)下,靠命名约定隔离,不能按服务拆子目录。
- 迁移工具通过文件系统扫描加载迁移,和 Composer autoload 无关;
"autoload"里无需映射迁移目录 - 文件名必须全局唯一,推荐用时间戳 + 服务前缀:
20230515102233_add_user_service_profile_table.php,否则doctrine:migrations:status会混乱 - Doctrine 可用
--filter="UserService"筛选类名匹配的迁移(v3.5+),Laravel 则需在up()中加if (! class_exists('UserService')) { return; }跳过 - 严禁用
--path指向子包目录——这会让版本表记录错误路径,后续回滚失效
最易被忽略的一点:迁移脚本是否生效,和 composer install 是否成功没有直接关系,而取决于当前工作目录是否为项目根、.env 是否真实存在且非 .env.example、以及数据库服务是否已在后台启动并可连通。这些条件全满足之前,任何钩子或自定义命令都只是空转。











