はじめに
こんにちは。先日から、今となっては珍しい(多分)、フレームワーク無しのPure PHPで構築されているプロジェクトに関わっています。
フレームワークを使うことが絶対正しいというわけではないのですが、エンジニアが数人関わる状況で個々がコードを書き散らす状況も生まれていて、せめてDBアクセス部分だけでも統一化するため、ORMの導入を検討した結果、現状で使用例が多そうなEloquentを採用しました。
今回の記事は導入からベーシックな使い方までの備忘録的なものです。
Eloquentとは
ORMのひとつで、PHPフレームワークのLaravelで採用されています。RailsのORMであるActiveRecordライクに使えるとのこと。
一方でDBファサードというクエリビルダも含んでおり、こちらは生でSQLを組み立てていくのに近い形で使えます。
前者は単純なCRUDをする時に、後者は複雑なテーブル結合をしつつ
COUNT()
の結果だけが欲しい、というような集計系の実装で…という感じで使い分けるといいのかな、と感じています。
Laravel5のアーキテクチャから学ぶより良いクラス設計
ORMって何ぞ?という方はこちらをどうぞ。
オブジェクト関係マッピング
Ormとの付き合い方
導入
稼働中のプロジェクトに組み込むので、なるべく他のコードは汚したくありません。プロジェクト内の任意の場所に新しくディレクトリを作成し、その中でComposerを使いインストールします。
私はCentOS6および7で確認していますが、PHPさえインストールされていれば、OS環境による差異は無いと思います。
導入手順はこちらのページをお読みいただければ、ほぼ完結します。
Composerインストール
PHPのパッケージ管理ツールComposerは、2018年10月現在、PHP5.3.2以上で動作します。現在サポートが続いてるCentOS6のBaseリポジトリでyum installできるバージョンが5.3.3ですから、それに合わせているのでしょうか。
ただし5.3系でComposerを入れようとすると、PHPのアップデートを促す警告がしつこいくらい出ます。PHP5.6すら2018年いっぱいでサポートが切れますので、当然ですね…。
1 2 3 4 5 6 7 | $ mkdir ./src && cd ./src $ curl -sS https://getcomposer.org/installer | php All settings correct for using Composer Downloading... Composer (version 1.7.2) successfully installed to: /home/nomura/src/composer.phar Use it: php composer.phar |
Eloquentインストール
composerでインストールする
illuminate/database
がパッケージ名で、このパッケージで実装されているORMがEloquentです。
illuminate/database
はORMとクエリビルダを内包していて、それぞれの記述方法でDBにアクセスできます(後述)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $ ./composer.phar require illuminate/database Using version ^5.7 for illuminate/database ./composer.json has been created Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 10 installs, 0 updates, 0 removals As there is no 'unzip' command installed zip files are being unpacked using the PHP zip extension. This may cause invalid reports of corrupted archives. Installing 'unzip' may remediate them. - Installing symfony/polyfill-mbstring (v1.9.0): Loading from cache ... ... illuminate/database suggests installing illuminate/pagination (Required to paginate the result set (5.7.*).) Writing lock file Generating autoload files |
DB接続
illuminate/database
公式のREADME.mdを参考にするだけで、ほぼ迷うことはないと思います(和訳もありました)。
このページを参考に、PHPからDB接続するコードを作成します(下記コードはローカルのMySQLに接続する方法です)。
vi ./database.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php use Illuminate\Database\Capsule\Manager as Capsule; $capsule = new Capsule; $capsule->addConnection([ 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'database', 'username' => 'root', 'password' => 'password', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', ]); $capsule->setAsGlobal(); $capsule->bootEloquent(); |
以上がDB接続のために最低限必要なコードとなり、上記コードを記述したPHPファイルを読み込めばOKです。
モデルクラス作成
illuminate\Database\Eloquent\Model
を継承したクラスを作成します。
vi ./User.php
1 2 3 4 | <?php require_once dirname(__FILE__).'/database.php'; use Illuminate\Database\Eloquent\Model; class User extends Model {} |
実際に使う
1 2 3 4 5 6 7 8 9 | <?php define('SRC_DIR', dirname(__FILE__)); require_once(SRC_DIR . '/vendor/autoload.php'); require_once(SRC_DIR . '/database.php'); require_once(SRC_DIR . '/User.php'); $users = User::all(); // *1 $users_array = $capsule::table('users')->where('name', '=', 'taro')->get(); // *2 $users = User::hydrate($users_array); // *3 |
*1〜*3は、いずれもUserテーブルからレコードを取得しています。メソッド名の意味が全く違うので想像しやすいと思いますが、それぞれ違う検索をしています。
- *1はEloquent入門的なコードでよく出てきますが、全件取得メソッドです。総レコード数が10件などの小さなテーブルならいいのですが、レコードが1000件あるテーブルなら1000件取得してしまうので、実際は*2や*3のようなコードをよく使うと思います。
- *2は前述のDBファサードによる検索で、ORMではなくクエリビルダを使って検索を実行しています。一見してどんなクエリが作られるのか想像しやすいのがメリットだと思いますが、返ってくるデータは配列です。
せっかくEloquentを導入しているのにモデルクラスのメソッドを使えないのは勿体無いので、なるべくモデルクラスとして取得したいところです。
ただし*2は複数のテーブルをJOINするなどの複雑なクエリを構築しやすく、集計系の機能にはこちらが向いているかと思っています。 - *3のように
hydrate()
を使うと、*2で取得した配列をCollectionに変換して返してくれます。Collectionは配列のように扱えて、foreachなどでレコードを1行ずつモデルクラスとして取得できます。
さいごに
EloquentをORMライブラリとして使うにあたり、導入はとても簡単で、かつ既存コードへの影響を抑えられるのが有り難いです。また、ActiveRecordライクなORMということで、他言語のORMを使う際も理解が早くなりそうという期待もあります。