phpmigでマイグレーションを行う

#phpmigとは
phpmigは、フレームワークによらないマイグレーションツールです。
laravelやFuelPHPなどのフレームワークでは標準のマイグレーションツールが存在しますが、素のPHPを使う場合に適していません。
（各フレームワークのマイグレーションのみを使う方法もありますが）
そこで今回は、マイグレーションにphpmigの利用を考えます

##インストール方法
まずはじめに、phpmig 及び pimpleのインストールを行います。
インストールはcomposerにて行います。

```
//phpmigのインストール
$ composer require davedevelopment/phpmig

//pimpleのインストール
$ composer require pimple/pimple
```

##初期設定
次に、phpmigの初期設定を行います。

```
//ｐｈｐmigの設定ファイルphpmig.phpを作成
$ vendor/bin/phpmig init
```

今回はMAMPのMySQLに接続をします。

```phpmig.php
<?php

use \Phpmig\Adapter;
use Pimple\Container;

$container = new Container();

//DBの接続情報
$container['db'] = function(){
	$dbh = new PDO('mysql:dbname='データベース名';host=127.0.0.1;port=8889;charset=utf8','ユーザー名', 'パスワード');
	$dbh -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	return $dbh;
};

//マイグレーションのバージョン情報の保存
// replace this with a better Phpmig\Adapter\AdapterInterface

//デフォルトでは、ファイルにバージョン情報を保存します。
//$container['phpmig.adapter'] = new Adapter\File\Flat(__DIR__ . DIRECTORY_SEPARATOR . 'migrations/.migrations.log');

//DBにバージョン情報を保存する
$container['phpmig.adapter'] = function ($container){
	return new Phpmig\Adapter\PDO\Sql($container['db'], 'migrations');
};

$container['phpmig.migrations_path'] = __DIR__ . DIRECTORY_SEPARATOR . 'migrations';

// You can also provide an array of migration files
// $container['phpmig.migrations'] = array_merge(
//     glob('migrations_1/*.php'),
//     glob('migrations_2/*.php')
// );

return $container;
```
データベース、ユーザー名、パスワードは自身の環境に応じて変更して下さい。
デフォルトのユーザー名、パスワードは'root','root'です。
ローカルのMySQLに接続する場合、host=localhostでは下記のエラーメッセージで接続できません。

```
SQLSTATE[HY000] [2002] No such file or directory 
```

そのため、host=127.0.0.1;port=8889　とホストとポートを指定して接続をしています。
ポート番号は自身のMAMP環境にて確認して下さい
MAMP起動後、上部メニューのMAMP>Preferences...>Ports>MySQL Portにて確認できます。デフォルトの場合、port=8889です

##マイグレーションファイルの作成
マイグレーションファイルを作成します

```
//generate ファイル名 で作成します
$ vendor/bin/phpmig generate AddTests
+f ./migrations/20191123103029_AddTests.php
```

これにより、マイグレーションファイルが作成されます

```./migrations/20191123103029_AddTests.php
<?php

use Phpmig\Migration\Migration;

class AddTests extends Migration
{
    /**
     * Do the migration
     */
    public function up()
    {

    }

    /**
     * Undo the migration
     */
    public function down()
    {

    }
}
```

up()にマイグレーションを、down()にロールバック処理を記述します。
詳しい記述方法は[GitHub](https://github.com/davedevelopment/phpmig)を参照して下さい。
シンプルに書くには、SQL文にて記述できます。

```./migrations/20191123103029_AddTests.php
<?php

use Phpmig\Migration\Migration;

class AddTests extends Migration
{
    /**
     * Do the migration
     */
	public function up()
	{
		$sql ="
		CREATE TABLE tests(
			`id` integer(11) NOT NULL AUTO_INCREMENT,
			`name` varchar(190) NOT NULL,
			`delete_flg` boolean NOT NULL DEFAULT false,
			`created_at` datetime DEFAULT CURRENT_TIMESTAMP(),
			`updated_at` datetime DEFAULT CURRENT_TIMESTAMP(),
			PRIMARY KEY (`id`)
			);
			";
		$container = $this -> getContainer();
		$container['db']->query($sql);
	}

	/**
     * Undo the migration
     */
	public function down()
	{
		$sql = "
		DROP TABLE tests
		";
		$container = $this->getContainer();
		$container['db']->query($sql);
	}
}
```

SQL文の書き方については、公式などを参照して下さい。
テーブル、カラムの作成、編集だけでなく、データの挿入、編集なども行うことができます。

##マイグレーションの実行
次に、作成したファイルに基づいてマイグレーションを実行します。

```
//マイグレーションの実行
$ vendor/bin/phpmig migrate

//ファイルを指定したい場合、ファイルのIDを指定します（ファイル名の前の数字）
//20191123103029_AddTests.phpの場合、
$ vendor/bin/phpmig up -v 20191123103029
 == 20191123103029 AddTests migrating
 == 20191123103029 AddTests migrated 0.0017s
```

マイグレーションの履歴は、statusにて確認できます。

```
//ステータスの確認
$ vendor/bin/phpmig status
 Status   Migration ID    Migration Name 
-----------------------------------------
     up  20191123103029  AddTests
```

##ロールバック
ロールバックの実行をします。

```
//最後のマイグレーションをロールバックする
$ vendor/bin/phpmig rollback

//IDを指定してロールバックする
$ vendor/bin/phpmig status
 Status   Migration ID    Migration Name 
-----------------------------------------
     up  20191122055928  CreateReviewsTable
     up  20191122062009  CreateRegistersTable
     up  20191122062033  CreateScoresTable
     up  20191122062534  CreateAssessmentsTable
     up  20191122081610  CreateLanguagesTable
     up  20191122081837  CreateSpansTable
     up  20191122082550  InsertLanguages20191122
     up  20191123103029  AddTests

//指定したIDのマイグレーション後までロールバックします
$ vendor/bin/phpmig rollback -t 20191122062033
 == 20191123103029 AddTests reverting
 == 20191123103029 AddTests reverted 0.0017s
 == 20191122082550 InsertLanguages20191122 reverting
 == 20191122082550 InsertLanguages20191122 reverted 0.0022s
 == 20191122081837 CreateSpansTable reverting
 == 20191122081837 CreateSpansTable reverted 0.0033s
 == 20191122081610 CreateLanguagesTable reverting
 == 20191122081610 CreateLanguagesTable reverted 0.0041s
 == 20191122062534 CreateAssessmentsTable reverting
 == 20191122062534 CreateAssessmentsTable reverted 0.0033s

$ vendor/bin/phpmig status
 Status   Migration ID    Migration Name 
-----------------------------------------
     up  20191122055928  CreateReviewsTable
     up  20191122062009  CreateRegistersTable
     up  20191122062033  CreateScoresTable
   down  20191122062534  CreateAssessmentsTable
   down  20191122081610  CreateLanguagesTable
   down  20191122081837  CreateSpansTable
   down  20191122082550  InsertLanguages20191122
   down  20191123103029  AddTests

//全てロールバックする
$ vendor/bin/phpmig rollback -t 0
```

###参考リンク
https://qiita.com/hypermkt/items/e48ca78f626faf23b41a
https://qiita.com/ichigotake/items/9ad9a83b5cc65a23d971
https://qiita.com/iakio/items/e9ae9fd537760b33a305