如何在执行php artisan migrate命令后触发自定义事件
迁移完成后自动执行字段新增与数据复制操作方案
以下是两种适配不同场景的实现方式:
方案1:每次迁移结束后自动触发(适配需要持续检测执行的场景)
Laravel 自带迁移完成事件,可以直接监听实现需求,不需要自行检测迁移状态:
- 第一步:打开
app/Providers/EventServiceProvider.php,在$listen属性中注册事件与监听器的映射关系:
protected $listen = [ \Illuminate\Database\Events\MigrationsEnded::class => [ \App\Listeners\HandleFieldAfterMigration::class, ], ];
- 第二步:执行命令生成对应的监听器类:
php artisan make:listener HandleFieldAfterMigration - 第三步:编辑生成的监听器文件,在
handle方法中写入字段新增、数据复制逻辑,注意添加字段存在性判断,避免重复执行报错:
use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\DB; public function handle(\Illuminate\Database\Events\MigrationsEnded $event) { // 此处替换为你自己的表名、新字段名、原有字段名 $targetTable = '你的表名'; $newColumn = '新增字段名'; $sourceColumn = '原有数据字段名'; if (!Schema::hasColumn($targetTable, $newColumn)) { // 新增字段,字段属性根据实际需求调整 Schema::table($targetTable, function (Blueprint $table) use ($newColumn) { $table->string($newColumn)->nullable(); }); // 复制原有字段数据到新字段 DB::table($targetTable)->update([ $newColumn => DB::raw($sourceColumn) ]); } }
提示:如果需要限制执行环境,可以在逻辑开头添加if (!app()->environment('local')) return;,避免线上环境误操作。
方案2:单次执行字段新增与数据复制(适配仅需执行一次的常规场景)
如果该操作只需要执行一次,不需要每次迁移后都检测,直接创建独立迁移文件即可,更简单轻量:
- 第一步:执行命令生成迁移文件,替换对应表名:
php artisan make:migration add_你的新字段名_to_你的表名_table - 第二步:编辑生成的迁移文件,修改
up和down方法:
use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\DB; public function up() { $targetTable = '你的表名'; $newColumn = '新增字段名'; $sourceColumn = '原有数据字段名'; Schema::table($targetTable, function (Blueprint $table) use ($newColumn) { $table->string($newColumn)->nullable(); }); DB::table($targetTable)->update([ $newColumn => DB::raw($sourceColumn) ]); } public function down() { Schema::table('你的表名', function (Blueprint $table) { $table->dropColumn('新增字段名'); }); }
- 第三步:执行
php artisan migrate即可完成操作。
内容的提问来源于stack exchange,提问作者A4fam
相关产品推荐
相关产品推荐

