如何在Laravel中创建自定义make:migration命令并预填充表结构
Laravel自定义迁移生成命令解决方案
你的思路是正确的,扩展MigrationCreator是Laravel官方支持的自定义迁移模板与逻辑的常规方案。下面是完整的可运行代码实现:
1. 创建自定义MigrationCreator类
创建app/Database/Migrations/CustomMigrationCreator.php,继承原类并实现自定义填充逻辑:
<?php namespace App\Database\Migrations; use Illuminate\Database\Migrations\MigrationCreator; use Illuminate\Filesystem\Filesystem; class CustomMigrationCreator extends MigrationCreator { public function __construct(Filesystem $files, string $customStubPath) { parent::__construct($files, $customStubPath); } /** * 重写Stub填充方法,替换自定义标签 */ protected function populateStub($name, $table, $create, $stub) { // 先执行父类的默认填充逻辑 $stub = parent::populateStub($name, $table, $create, $stub); // 替换自定义标签,生成预填充字段 return str_replace( '{{custom_fields}}', $this->generatePredefinedFields($table), $stub ); } /** * 根据表名生成预填充字段定义 */ protected function generatePredefinedFields($table) { $fields = match ($table) { 'users' => [ '$table->string(\'name\');', '$table->string(\'email\')->unique();', '$table->timestamp(\'email_verified_at\')->nullable();', '$table->string(\'password\');', '$table->rememberToken();', ], 'posts' => [ '$table->string(\'title\');', '$table->text(\'content\');', '$table->foreignId(\'user_id\')->constrained();', ], default => [ '$table->string(\'name\');', ], }; return implode("\n ", $fields); } }
2. 实现自定义迁移命令
修改app/Console/MyCustomMakeMigrationCommand.php,注入Filesystem实例并初始化自定义Creator:
<?php namespace App\Console; use App\Database\Migrations\CustomMigrationCreator; use Illuminate\Console\Command; use Illuminate\Filesystem\Filesystem; use Illuminate\Database\Console\Migrations\BaseCommand; class MyCustomMakeMigrationCommand extends BaseCommand { protected $name = 'make:custom-migration'; protected $description = '生成带预填充字段的自定义迁移文件'; protected $creator; public function __construct(Filesystem $files) { parent::__construct(); // 指定自定义Stub文件路径 $customStubPath = resource_path('stubs/migrations'); $this->creator = new CustomMigrationCreator($files, $customStubPath); } /** * 执行命令 */ public function handle() { $name = trim($this->input->getArgument('name')); $table = $this->input->getOption('table'); $create = $this->input->getOption('create'); // 处理--create参数自动绑定表名 if (! $table && is_string($create)) { $table = $create; } // 生成迁移文件 $file = $this->creator->create( $name, $this->getMigrationPath(), $table, $create !== false ); $this->components->info(sprintf('迁移文件生成成功:%s', $file)); } /** * 定义命令参数 */ protected function getArguments() { return [ ['name', Command::REQUIRED, '迁移文件名称'], ]; } /** * 定义命令选项 */ protected function getOptions() { return [ ['create', null, Command::VALUE_OPTIONAL, '指定要创建的表名'], ['table', null, Command::VALUE_OPTIONAL, '指定要操作的表名'], ]; } }
3. 创建自定义Stub模板
在resources/stubs/migrations目录下创建create.stub(对应创建表的迁移模板):
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * 执行迁移 */ public function up(): void { Schema::create('{{table}}', function (Blueprint $table) { $table->id(); {{custom_fields}} $table->timestamps(); }); } /** * 回滚迁移 */ public function down(): void { Schema::dropIfExists('{{table}}'); } };
如果需要支持修改表的迁移,可同时创建stub.stub模板。
4. 注册自定义命令
在app/Console/Kernel.php的$commands数组中添加自定义命令:
protected $commands = [ \App\Console\MyCustomMakeMigrationCommand::class, ];
5. 使用命令
运行以下命令生成带预填充字段的迁移:
# 创建users表的迁移,自动填充用户字段 php artisan make:custom-migration create_users_table --create=users # 生成修改posts表的迁移 php artisan make:custom-migration add_status_to_posts_table --table=posts
内容的提问来源于stack exchange,提问作者Peter de Groot
相关产品推荐
相关产品推荐

