【PHP】非Laravel環境(Native)でEloquentを使ってテーブルの作成

PHPのORMライブラリであるEloquentを使えば、データベースの実装(MySQLとかPostgreSQLとか)を気にせずにデータベース操作処理を実装できます。Eloquentはテーブルの作成や削除もサポートしていますが、多くの場合での利用方法は、LaravelでのMigrationではないでしょうか。本記事では、Laravelではない環境でEloquentを使ってデータベースの作成をするサンプルを記載します。

LaravelのMigrationで使うコードを手動で実行してみると

LaravelでデータベースのMigrationを行うためにartisanコマンドを実行すると、↓こんな感じのclassのひな型が生成されますね。商品(Merchandise)を管理する テーブルを作成するように書き換えてみました。

<?php

require "../vendor/autoload.php";

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateMerchandisesTable extends Migration
{
    public function up()
    {
        Schema::create('merchandises', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('category');
            $table->integer('price');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('merchandises');
    }
}

$creator = new CreateMerchandisesTable();
$creator->up();

Laravelでは、マイグレーションファイルを更新後、php artisan migrateを実行すれば、テーブルの更新や作成が行われますが、Laravel環境ではなく、EloquentをただのORMライブラリとして使いたいだけの環境ではどうすれば...?

このマイグレーションファイルのup()関数を実行すると、内部的にEloquentの処理が実行されてcreate tableしてくれそうですが、非Laravel環境でup()関数をコールしたところで、こんな感じのエラーになります。

Fatal error: Uncaught RuntimeException: A facade root has not been set. in C:\xampp\htdocs\orm_test\vendor\illuminate\support\Facades\Facade.php:350 Stack trace: #0 C:\xampp\htdocs\orm_test\Eloquent_test\Migration_error.php(30): Illuminate\Support\Facades\Facade::__callStatic('create', Array) #1 C:\xampp\htdocs\orm_test\Eloquent_test\Migration_error.php(46): CreateMerchandisesTable->up() #2 {main} thrown in C:\xampp\htdocs\orm_test\vendor\illuminate\support\Facades\Facade.php on line 350

処理内でDBファサードが死にます。
Laravelが動いていたら内部的に生成しているはずのオブジェクトインスタンスや実行されるはずの前処理が欠落しているためと思われます。そもそもデータベースの実装は何を使うとか、データベースサーバにアクセスするための認証情報とかを一切与えていませんね。

Eloquent単体で実行する方法

こんな感じのコードになるらしい。
データベースの実装はXAMPPバンドルのMariaDB(MySQL)を、テーブルはorm_testというDBの下に作るように指定しました。

<?php

require "../vendor/autoload.php";

use Illuminate\Database\Capsule\Manager as Capsule;

$capsule = new Capsule;

$capsule->addConnection([
    "driver" => "mysql",
    "host" => "127.0.0.1",
    "database" => "orm_test",
    "username" => "root",
    "password" => "xxxxxx"
]);

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

$capsule->schema()->create('merchandises', function ($table) {
    $table->increments('id');
    $table->string('name');
    $table->string('category');
    $table->integer('price');
    $table->timestamps();
});

上記のphpコードを実行することで、↓こんな感じにmerchandisesというテーブルが作成されました。

Capsuleというクラスのインスタンスを最初に作成します。addConnection()関数を使ってデータベースの情報を与えていますね。

上記のcreate()関数に与える関数オブジェクトの中身は、Laravel環境で実装するup()関数の中身とほぼ同じ構造ですね。
LaravelではMigrationクラスを拡張しますが、Eloquent単体ではCapsuleオブジェクトにデータベースをcreateするときの関数実装を直接与えればいいようです。

これを応用すれば、Runtimeでテーブルの作成・修正・削除が実装できそうです。
Runtimeにテーブル構造を変えるのはアプリケーションの設計としてはどうかという感じですが、アプリケーションのインストーラを実装したいときなんかは役に立ちそうです。

実行環境

  • xampp 8.2.4
  • Eloquent 10.8
{
    "require": {
        "illuminate/database": "10.8"
    }
}

参考資料

参考資料では、Capsuleオブジェクトを初期化するコードの部分は、別ファイル(bootstrap.php)として切り出すことを推奨しています。

コメント