前言
因为一些原因,我准备选用yaf
框架作为我们的主力开发框架,但是我还想要将Laravel
的数据库迁移功能给挪过来。所以就研究了一天相关功能。终于让我实现了。
文件简介
首先看一下项目目录:
代码语言:javascript复制yaf-base/
├── app
│ ├── Bootstrap.php
│ ├── controllers
│ │ └── Index.php
│ └── Models
│ └── UserBase.php
├── app.ini
├── bin
│ └── migrate.php
├── composer.json
├── composer.lock
├── migrations
│ └── 2014_10_12_000000_create_users_table.php
├── public
│ └── index.php
├── README.md
└── vendor
这里是composer.json
文件的内容:
{
"require":{
"php":">=7.2",
"illuminate/database":"^6.4",
"illuminate/filesystem":"^6.4",
"illuminate/events":"^6.4",
"illuminate/config":"^6.4",
"illuminate/console":"^6.4"
},
"repositories":{
"packagist":{
"type":"composer",
"url":"https://mirrors.aliyun.com/composer/"
}
}
}
然后下面是migrations/2014_10_12_000000_create_users_table.php
<?php
use IlluminateContainerContainer;
use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
可以看到这个跟Laravel的迁移文件是一样的。
第三个文件就是bin/migrate.php
<?php
use IlluminateConfigRepository;
use IlluminateConsoleOutputStyle;
use IlluminateContainerContainer;
use IlluminateDatabaseConnectorsConnectionFactory;
use IlluminateDatabaseConsoleMigrationsTableGuesser;
use IlluminateDatabaseDatabaseManager;
use IlluminateDatabaseMigrationsDatabaseMigrationRepository;
use IlluminateDatabaseMigrationsMigrationCreator;
use IlluminateDatabaseMigrationsMigrator;
use IlluminateDatabaseSchemaBuilder;
use IlluminateEventsDispatcher;
use IlluminateFilesystemFilesystem;
use IlluminateSupportFacadesFacade;
use IlluminateSupportStr;
use SymfonyComponentConsoleInputArgvInput;
use SymfonyComponentConsoleOutputConsoleOutput;
define("ROOT_PATH", realpath(__DIR__ . "/../"));
require ROOT_PATH . "/vendor/autoload.php";
if (!isset($argv[1])) {
$argv[1] = null;
}
$container = new Container();
$config = new Repository();
$config->set("database", [
"default" => "mysql",
"connections" => [
"mysql" => [
'driver' => 'mysql',
'url' => "",
'host' => "127.0.0.1",
'port' => "3306",
'database' => "test",
'username' => "root",
'password' => "baoguoxiao",
'unix_socket' => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => [],
]
]
]);
$container->instance("config", $config);
$file = new Filesystem();
$container->singleton("db", function ($container) {
$db = new DatabaseManager($container, new ConnectionFactory($container));
$db->connection("mysql");
return $db;
});
Facade::setFacadeApplication($container);
Container::setInstance($container);
/**
* 执行迁移命令如果出现 SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes 错误则开启此行代码即可解决问题
*/
//Builder::defaultStringLength(191);
$repository = new DatabaseMigrationRepository($container["db"], "migrations");
$event = new Dispatcher($container);
$migrator = new Migrator($repository, $container["db"], $file, $event);
$output = new OutputStyle(new ArgvInput(), new ConsoleOutput());
if ($argv[1] == "create") {
$creator = new MigrationCreator($file);
$name = Str::snake($argv[2]);
[$table, $create] = TableGuesser::guess($name);
try {
$file_path = $creator->create($name, ROOT_PATH . "/migrations", $table, $create);
$file_path = pathinfo($file_path, PATHINFO_FILENAME);
$output->success("Created Migration: {$file_path}");
} catch (InvalidArgumentException $exception) {
$output->error($exception->getMessage());
}
} elseif ($argv[1] == "up") {
if (!$migrator->repositoryExists()) { // migrate:install
$repository->createRepository();
}
$migrator->setOutput($output)->run(ROOT_PATH . "/migrations", [
"pretend" => false,
"step" => false
]);
} elseif ($argv[1] == "down") {
if (!$migrator->repositoryExists()) { // migrate:install
$repository->createRepository();
}
$migrator->setOutput($output)->rollback(ROOT_PATH . "/migrations", [
"pretend" => false,
"step" => 0
]);
}else {
$output->text(<<<EOF
操作方法:
php bin/migrate.php create {xxx} 创建迁移,命名规则为Laravel
php bin/migrate.php up 执行迁移
php bin/migrate.php down 回滚迁移
EOF
);
}
执行操作
执行迁移命令:
代码语言:javascript复制$ php bin/migrate.php up
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.11 seconds)
迁移回滚:
代码语言:javascript复制$ php bin/migrate.php down
Rolling back: 2014_10_12_000000_create_users_table
Rolled back: 2014_10_12_000000_create_users_table (0.03 seconds)
创建表:
代码语言:javascript复制$ php bin/migrate.php create create_demo_table
[OK] Created Migration: 2019_11_06_220957_create_demo_table
查看一下目录:
代码语言:javascript复制$ tree -L 2 ./yaf-base/
./yaf-base/
├── app
│ ├── Bootstrap.php
│ ├── controllers
│ └── Models
├── app.ini
├── bin
│ └── migrate.php
├── composer.json
├── composer.lock
├── migrations
│ ├── 2014_10_12_000000_create_users_table.php
│ └── 2019_11_06_220957_create_demo_table.php
├── public
│ └── index.php
├── README.md
└── vendor
可以看到多了一个2019_11_06_220957_create_demo_table.php
查看以下里面的内容:
代码语言:javascript复制<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
class CreateDemoTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('demo', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('demo');
}
}
跟Laravel
丝毫不差。
总结
通过此次的重现,我对于Laravel
的容器理解更加深刻了。对于Laravel
的所有都注入到容器中的想法表示敬佩。
同时对于提取了这一套迁移方法表示可以同样用在基础框架中,非常实用。