
codeigniter 4 原生不支持直接运行指定迁移文件,但可通过自定义 cli 命令调用 `migrationrunner::force()` 方法实现精准迁移,适用于模块化项目中按组(如 blog、sales)独立执行特定迁移。
在模块化 CodeIgniter 4 项目中,常需按业务域(如 blog、sales、storage)组织迁移文件,并支持仅执行某模块的特定迁移——例如部署新销售功能时,仅运行 sales 目录下的迁移,而非全量迁移。遗憾的是,CI4 官方 spark migrate 命令仅支持按版本号(--force 到某时间戳)、命名空间或全部回滚,不提供“仅运行某一个 .php 迁移文件”的内置指令。
所幸,CI4 的 MigrationRunner 类公开了关键方法 force($file, $namespace = 'App', $group = 'default'),它允许传入完整文件路径(相对于 ROOTPATH),跳过版本校验与依赖检查,直接执行该文件中的 up() 方法。我们可基于此构建一个高复用性的自定义命令 migrate:file。
✅ 快速创建自定义命令
在终端执行以下命令生成骨架类:
php spark make:command MigrateFile --command migrate:file --group Database --suffix Command
该命令将在 app/Commands/ 下生成 MigrateFileCommand.php。替换其内容为以下精简可靠的实现:
[options]';
protected $arguments = [
'file-path' => 'Full path to migration file (relative to ROOTPATH), e.g. "app/Database/Migrations/2023-01-01-000000_CreateOrdersTable.php"'
];
protected $options = [
'--namespace' => 'Migration namespace (default: "App")',
'--dbgroup' => 'Database group name (default: "default")',
];
public function run(array $params)
{
$filePath = $params[0] ?? null;
if (!$filePath) {
CLI::error('Missing required argument: migration file path.');
$this->showHelp();
return;
}
$namespace = CLI::getOption('namespace') ?: 'App';
$dbgroup = CLI::getOption('dbgroup') ?: 'default';
CLI::write("Executing migration: {$filePath} (NS: {$namespace}, DB: {$dbgroup})", 'yellow');
$runner = Services::migrations();
try {
if (!$runner->force(ROOTPATH . $filePath, $namespace, $dbgroup)) {
CLI::error('Migration execution failed.', 'red');
return;
}
foreach ($runner->getCliMessages() as $msg) {
CLI::write($msg);
}
CLI::write('✅ Migration completed successfully.', 'green');
} catch (\Throwable $e) {
CLI::error("Error: {$e->getMessage()}", 'red');
}
}
}? 注意:确保迁移文件路径使用正斜杠 /(Windows 也兼容),且必须包含 .php 扩展名;路径以 ROOTPATH 为根,如 app/Database/Migrations/...,而非 APP_PATH 或 WRITEPATH。
? 使用示例
执行单个迁移(默认 App 命名空间 + default 数据库):
php spark migrate:file "app/Database/Migrations/2023-05-10-120000_AddSalesDiscounts.php"
指定命名空间(如模块化结构 Modules\Sales)和数据库组:
php spark migrate:file "Modules/Sales/Database/Migrations/2023-05-10-120000_AddSalesDiscounts.php" \ --namespace "Modules\Sales" \ --dbgroup "sales_db"
查看帮助文档:
php spark help migrate:file
? 模块化批量执行(进阶用法)
回到你原始需求——按模块键(如 $files['sales'])批量运行多个迁移,可在控制器或服务中封装逻辑:
// 在任意服务类中
public function runModuleMigrations(string $module): bool
{
$files = [
'blog' => ['app/Database/Migrations/2023-01-01-000000_CreatePostsTable.php'],
'sales' => [
'app/Database/Migrations/2023-05-10-120000_AddSalesDiscounts.php',
'app/Database/Migrations/2023-05-11-143000_AddOrderStatuses.php'
],
'storage' => ['app/Database/Migrations/2023-02-20-090000_CreateFilesTable.php']
];
$migrationRunner = \Config\Services::migrations();
foreach ($files[$module] ?? [] as $path) {
if (!$migrationRunner->force(ROOTPATH . $path, 'App')) {
log_message('error', "Failed to run migration: {$path}");
return false;
}
}
return true;
}⚠️ 重要提醒
- force() 不校验迁移顺序或已执行状态,请确保手动维护执行顺序(如按时间戳升序);
- 生产环境慎用,建议仅用于开发/部署脚本,避免破坏迁移历史一致性;
- 若需幂等性与状态追踪,仍应优先使用标准 spark migrate --all 流程,将模块迁移纳入统一版本序列。
通过该方案,你不仅解决了“运行单个迁移”的技术瓶颈,更获得了面向模块的灵活迁移调度能力——让 CI4 的数据库演进真正匹配现代分层架构的演进节奏。










