本エントリでは、ピュアなPHPで書かれたWebアプリケーションにLaravel標準のORMであるEloquent
を導入した際にやったことを簡単にまとめています。
実施した際はPHP5.6でしたが、学習のためも含めて本エントリ内のソースコードはPHP7.2で動作させています。
経緯でも書かせていただいていますが、データベースはSQLite3を使っていますが、macOSで動かす場合にはすでにインストールされていると思うのでsqlite3 -version
で確認してから動かしてみてください。
経緯
事前に、Eloquent
を導入するに至った経緯を簡単に説明しておきたいと思います。
SQLite3をデータソースにしたレガシーなプロジェクト
あるプロジェクトが素のPHPで書かれています。すべてのAPIがその1つのモノリシックなPHPアプリケーションとなっています。
ここで問題となっているのが、データベースとしてSQLite3を利用していることでした。
SQLite3はデータベースをファイルとして扱うため、
- ファイルI/Oが遅くなる
- サーバの分散ができない
という問題を抱えています。
また、行ロックではなくテーブルロックであるため書き込みが多いようなアプリケーションには向かない、という問題もありました。
嬉しいことに、サービスの成長によってサーバをスケールアウトできるようにしてリソースに余裕がほしいという要望が出てくることになりました。
Laravelへの移行は一朝一夕ではできない
ほかのプロジェクトではLaravelを利用しており、データベースは一部SQLite3を引き継いでいるものの、多くはMySQL(AWS Aurora)です。
ただ、前述のアプリケーションの大きさゆえに、Laravel + MySQLへの移行はすぐには難しく、まずは、MySQLへの移行をする準備として、Laravel標準のORMであるEloquent
を既存のコードに入れていくという運びとなりました。
クライアントごとにSQLite3のファイルが異なる
また、管理していたSQLite3のファイルは複数存在しました。
グローバルな情報を扱うアプリケーションに唯一のデータベースと、クライアントにつき幾つか存在するデータベースがあり、リクエストの方法によって、クライアントごとに書き込みや参照をするデータベースを変えるということをしていました。
今回は、こちらの話には触れず、Eloquent
の導入部分のみを書きます。
こちらの話も今後別記事として書きたいと思います。
やったこと
あとは淡々とやっていったこと、その際に調べたことを書きます。
※ 簡単な例を用意しました。
https://github.com/zuckeyM-17/php-sandbox/tree/master/use-eloquent-at-pure-php-app
4ステップでできます。
- PHPのバージョン管理ツールであるcomposerをインストール
- illuminate/databaseというパッケージをインストール
- illuminate/databaseの設定
- 必要なEloquentモデルを作成
1. PHPのバージョン管理ツールであるcomposerをインストール
$ cd ./src $ curl -sS https://getcomposer.org/installer | php
用意した例では、環境を汚さないようcomposer.pharというファイルをsrcディレクトリ直下にダウンロードするという方法を取っています。
2. illuminate/databaseというパッケージをインストール
$ ./composer.phar require illuminate/database
ステップ1で用意したcomposer.pharを利用して illuminate/databaseというパッケージをインストールします。
Larvelを構成するライブラリはすべてgithubのilluminateというところに所属します。
そこでdatabase部分を担当する、illuminate/databaseをインストールするわけです。
illuminate/databaseのREADME.mdの日本語訳が見当たらなかったので、和訳しました。
3. illuminate/databaseの設定
ほぼ、illuminate/databaseのREADMEを読めば簡単に作ることができます。
READMEではデータソースがMySQLだったため、例ではSQLiteで指定しました。
SQLiteで必要な項目は、ファイルへのパスのみなので簡単です。
<?php use Illuminate\Database\Capsule\Manager as Capsule; $capsule = new Capsule; $capsule->addConnection([ 'driver' => 'sqlite', 'database' => SRC_DIR . '/app.db', // ここにSQLiteファイルへのパスを入れる ]); $capsule->setAsGlobal(); $capsule->bootEloquent();
4. 必要なEloquentモデルを作成
illuminate\Database\Eloquent\Modelというクラスを継承したモデルクラスを作成します。
EloquentはActiveRecordの実装となっているため、Model
クラスはテーブルについて1つ作成し、Model
クラスに生えた便利なメソッドでテーブルにアクセスすることができます。
最低限な実装をすると以下のようになります。
<?php require_once dirname(__FILE__).'/database.php'; use Illuminate\Database\Eloquent\Model; class Book extends Model {}
これで、Bookモデルがアプリケーションで使えるようになりました。
以下ではBookの中身を取り出して表示しています。
<?php define('SRC_DIR', dirname(__FILE__)); require_once(SRC_DIR . '/vendor/autoload.php'); require_once(SRC_DIR . '/database.php'); require_once(SRC_DIR. '/Book.php'); $books = Book::all(); foreach($books as $book) { echo $book->isbn, "\t" , $book->name, "\t", $book->author, "\t", $book->created, "\t", $book->updated, PHP_EOL; }
まとめ
Eloquent
をライブラリとして導入しました。
illuminate/database
というパッケージを入れることで可能でした。
ただ、 illuminate/database
単体では、マイグレーション周りをサポートしていないらしく、今回のユースケースでは既存のテーブルに対して行うということだったので、ただ純粋にEloquent
をライブラリとして使うということを目的とすると、調査が甘かったようです。
Eloquent
のModelは便利なメソッドがたくさん生えているので、そちらについても今後紹介して行こうと思います。
また、illuminateなどOSSとしてのLaravelのプロジェクトについて少し知識がついたので、これからもう少しソースコードをしっかり追っていきたいなとも思いました。
間違っている部分、この施策についてのフィードバックなどありましたら、いただけると嬉しいです!