一条命令快速搞定 Laravel 的数据库重置操作
说明
我们在日常开发中时常会遇到各种 migration 执行报错的问题,大部分情况下都是本地数据库的数据出现了问题。这个时候我们通常会通过以下 3 个步骤来对这个问题进行修复:
- 删除本地所有数据库表
- 重新执行 migration
- 重新运行 db:seed
如果每次都得将上面几个步骤手动操作一遍的话相信你也会崩溃的。因此我借助 Laravel 提供的自定义命令行功能把上面几个步骤简化为一个命令来快速修复这种问题。
$ php artisan project:reset
命令行创建
下面跟大家说下如何将此命令快速添加到 Laravel 项目中。
第一步你需要先创建一个 ProjectResetCommand
文件,不知道如何创建的可看 @Summer 写的 Laravel 5.1 Artisan 命令行实战
第二步则是将以下内容写入到 ProjectResetCommand
文件中。
app/Console/Commands/ProjectResetCommand.php:
<?php namespace App\Console\Commands;
use Illuminate\Console\Command;
use DB;
use App;
class ProjectResetCommand extends Command
{
protected $signature = 'project:reset {--force : enforce}';
protected $description = "Reset database";
public function __construct()
{
parent::__construct();
}
public function handle()
{
// 防呆操作
$this->productionCheckHint();
// fixing db:seed class not found
$this->execShellWithPrettyPrint('composer dump');
$this->info("Will delete all tables, and run the 'migrate' and 'db:seed' commands");
$this->nukeDatabase();
// 生成数据库迁移,同时数据填充
$this->call('migrate', [
'--seed' => 'yes',
'--force' => 'yes'
]);
}
// 清洗数据库
public function nukeDatabase()
{
$colname = 'Tables_in_' . env('DB_DATABASE');
$tables = DB::select('SHOW TABLES');
foreach ($tables as $table) {
$droplist[] = $table->$colname;
$this->info('Will delete table - ' . $table->$colname);
}
if (!isset($droplist)) {
$this->error('No table');
return;
}
$droplist = implode(',', $droplist);
DB::beginTransaction();
//turn off referential integrity
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
DB::statement("DROP TABLE $droplist");
//turn referential integrity back on
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
DB::commit();
$this->comment("All the tables have been deleted".PHP_EOL);
}
// 执行命令行并区块化打印结果
public function execShellWithPrettyPrint($command)
{
$this->info('---');
$this->info($command);
$output = shell_exec($command);
$this->info($output);
$this->info('---');
}
// 高危动作,生产环境下的防呆保护
public function productionCheckHint($message = '')
{
$message = $message ?: 'This is a "very dangerous" operation';
if (App::environment('production')
&& !$this->option('force')
&& !$this->confirm('Your are in「Production」environment, '.$message.'! Are you sure you want to do this? [y|N]')
) {
exit('Command termination');
}
}
}
最后在 Kernel.php
文件中添加 ProjectResetCommand
:
protected $commands = [
Commands\Inspire::class,
Commands\ProjectResetCommand::class,
];
至此,命令已可正常运行,Have fun!:sparkles: :sparkles: :sparkles:
本作品采用《CC 协议》,转载必须注明作者和本文链接
酷~
description 不对