Laravel 以外のプロジェクトで Illuminate Database を使う(応用編)

Laravel 以外のプロジェクトで Illuminate Database を使う(基本編)に続いて、応用編としてマイグレーションやシーディングをコマンドラインから実行できるようにします。

Laravel で使える artisan コマンドは単独のパッケージとして提供されていないので、Phinx というパッケージを利用します。Phinx 自身にマイグレーションやシーディングの機能があるので、こだわりがなければそのまま使ってもよいと思います。

ファイル構成

今回の記事のゴールとなるファイル構成は以下の通りです。

(project root)
│
├─database
│  │  
│  ├─migrations
│  │  └─20220604133106_create_user_table.php
│  │      
│  ├─Models
│  │  └─User.php
│  │      
│  ├─seeds
│  │  └─UserSeeder.php
│  │
│  ├─bootstrap.php
│  ├─Migration.php
│  ├─phinx.php
│  └─Seeder.php
│          
├─vendor
│  └─autoload.php
│
├─.env
├─composer.json
└─composer.lock

必要なパッケージのインストール

composer を使ってインストールします。

composer require robmorgan/phinx

設定ファイルの作成

Phinx の設定ファイルは、YAML や JSON で書くこともできますが、今回は .env ファイルの読み込みに phpdotenv を使いたいので、PHP で phinx.php を作成します。

<?php
$root_dir = dirname(__DIR__);
require_once($root_dir . '/vendor/autoload.php');

$dotenv = Dotenv\Dotenv::createImmutable($root_dir);

if (file_exists($root_dir . '/.env')) {
    $dotenv->load();
}

return
    [
        'paths' => [
            'migrations' => '%%PHINX_CONFIG_DIR%%/migrations',
            'seeds' => '%%PHINX_CONFIG_DIR%%/seeds'
        ],
        'seeder_base_class' => 'Seeder',
        'migration_base_class' => 'Migration',
        'environments' => [
            'default_migration_table' => 'phinxlog',
            'default_environment' => 'production',
            'production' => [
                'adapter' => $_ENV['DB_CONNECTION'],
                'host' => $_ENV['DB_HOST'],
                'name' => $_ENV['DB_DATABASE'],
                'user' => $_ENV['DB_USERNAME'],
                'pass' => $_ENV['DB_PASSWORD'],
                'port' => $_ENV['DB_PORT'],
                'charset' => $_ENV['DB_CHARSET'],
            ],
        ],
        'version_order' => 'creation'
    ];

マイグレーション

共通設定用のクラスの作成

マイグレーション時の共通の設定をするための Migration クラスを作成します。

<?php
$root_dir = dirname(__DIR__);
require_once($root_dir . '/vendor/autoload.php');

$dotenv = Dotenv\Dotenv::createImmutable($root_dir);

if (file_exists($root_dir . '/.env')) {
    $dotenv->load();
}

use Illuminate\Database\Capsule\Manager as Capsule;
use Phinx\Migration\AbstractMigration;

class Migration extends AbstractMigration
{
    /** @var \Illuminate\Database\Capsule\Manager $capsule */
    public Capsule $capsule;
    /** @var \Illuminate\Database\Schema\Builder $capsule */
    public \Illuminate\Database\Schema\Builder $schema;

    public function illuminateInit()
    {
        $this->capsule = new Capsule;
        $this->capsule->addConnection([
            'driver' => $_ENV['DB_CONNECTION'],
            'host' => $_ENV['DB_HOST'],
            'database' => $_ENV['DB_DATABASE'],
            'username' => $_ENV['DB_USERNAME'],
            'password' => $_ENV['DB_PASSWORD'],
            'charset' => $_ENV['DB_CHARSET'],
            'collation' => $_ENV['DB_COLLATION'],
        ]);

        $this->capsule->bootEloquent();
        $this->capsule->setAsGlobal();
        $this->schema = $this->capsule::schema();
    }

}

個別のマイグレーションファイルの作成

個別のマイグレーションファイルのひな型は、プロジェクトのルートディレクトリで以下のコマンドを実行すれば作成できます。

./vendor/bin/phinx create CreateUsersTable -c ./database/phinx.php

作成されたファイル(YYYYMMDDHHmmss_create_user_table.php)を編集します。

<?php
declare(strict_types=1);

use Illuminate\Database\Schema\Blueprint;

final class CreateUserTable extends Migration
{
    public function up(): void
    {
        $this->illuminateInit();

        $this->schema->create('users', function(Blueprint $table){
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->timestamps();
        });
    }
    public function down(): void
    {
        $this->illuminateInit();
        $this->schema->drop('users');
    }
}

マイグレーションの実行

マイグレーションファイルを作成したら、以下のコマンドでマイグレーションを実行します。

./vendor/bin/phinx migrate -c ./database/phinx.php

シーディング

共通設定用のクラスの作成

シーディング時の共通の設定をするための Seeder クラスを作成します。

<?php
$root_dir = dirname(__DIR__);
require_once($root_dir . '/vendor/autoload.php');

$dotenv = Dotenv\Dotenv::createImmutable($root_dir);

if (file_exists($root_dir . '/.env')) {
    $dotenv->load();
    $dotenv->required(['DB_CONNECTION', 'DB_DATABASE', 'DB_USERNAME', 'DB_PASSWORD']);
}

use Illuminate\Database\Capsule\Manager as Capsule;
use Phinx\Seed\AbstractSeed;

class Seeder extends AbstractSeed
{
    /** @var \Illuminate\Database\Capsule\Manager $capsule */
    public Capsule $capsule;

    public function illuminateInit()
    {
        $this->capsule = new Capsule;
        $this->capsule->addConnection([
            'driver' => $_ENV['DB_CONNECTION'],
            'host' => $_ENV['DB_HOST'],
            'database' => $_ENV['DB_DATABASE'],
            'username' => $_ENV['DB_USERNAME'],
            'password' => $_ENV['DB_PASSWORD'],
            'charset' => $_ENV['DB_CHARSET'],
            'collation' => $_ENV['DB_COLLATION'],
        ]);

        $this->capsule->bootEloquent();
        $this->capsule->setAsGlobal();
    }

}

個別のシーティングファイルの作成

個別のシーティングファイルのひな型は、プロジェクトのルートディレクトリで以下のコマンドを実行すれば作成できます。

./vendor/bin/phinx seed:create UserSeeder -c ./database/phinx.php

作成されたファイル(UserSeeder.php)を編集します。seeder_base_class を設定しているにもかかわらず、親クラスの設定が反映されないので、修正する必要があります。

<?php

class UserSeeder extends Seeder
{
    public function run()
    {
        $this->illuminateInit();

        $this->capsule::table('users')->insert([
            ['name' => 'テスト 太郎', 'email' => 'taro@example.com', 'password' => 'hoge', 'created_at' => '2022-06-01 00:00:00', 'updated_at' => '2022-06-01 00:00:00'],
        ]);
    }
}

シーティングの実行

シーディングファイルを作成したら、以下のコマンドでシーディングを実行します。

./vendor/bin/phinx seed:run -c ./database/phinx.php

個別のシーティングファイルだけを実行したいときは、以下のように指定することもできます。

./vendor/bin/phinx seed:run -c ./database/phinx.php -s UserSeeder
この記事を書いた人
グッドネイバー

“ Webに悩むお客さまの「よき隣人」でありたい ” をモットーに、Web システム開発(主に Laravel)、Web マーケティング支援の仕事をしています。お仕事のご依頼・ご相談はこちらからお気軽にどうぞ。

PHPLaravel