2013年9月9日月曜日

FuelPHPのクエリビルダを使いこなす

皆さん、FuelPHPしてますか?
今日はFuelPHPの多機能の中でもクエリビルダに注目してまとめます。

※下記の記載の実行環境は以下のとおりです(2013年9月9日現在
  • PHP5.5.3
  • PostgreSQL9.2.
  • FuelPHP1.6
まずクエリビルダですが公式ドキュメントはこちら

Database 使い方

基本的な使い方はこちらのブログが非常にわかりやすいです。

FuelPHPのクエリビルダを表にまとめた


さて、これだけ見れば単純なQueryについては十分使いこなせると思います。
ただ公式にも書いてなかったのですがWHERE句に関してはこれだけではありません。

$query->where('column_name_1', 'hoge');
$query->where('column_name_2', '>', 1);

//下記は同じSQLが発行される
$column_list = array(
    'column_name_1' => 'hoge',
    'column_name_2' => array('>' => 1),
);
$query->where($column_list);

//5.4以降だと配列が簡潔に
$column_list = [
    'column_name_1' => 'hoge',
    'column_name_2' => ['>' => 1],
];
$query->where($column_list);

と出来ます。
where()に直接配列を渡して実行できるわけです。
値の有無をチェックしたりループを回したりしながら何度もwhere()を呼ぶ必要はありません。
これは非常に使える場面が多いです。
それとバインディングもサポートしてます。

//公式
$query = DB::query("SELECT * FROM users WHERE username = :name")->param('name', 'value')->execute();
//param('name', 'value')→param(':name', 'value')でも動く
$query = DB::query("SELECT * FROM users WHERE username = :name")->param(':name', 'value')->execute();
//クエリビルダは':name'なら動く
>where(':name','value')->param(':name', 'value')->execute();

DB::queryを使う時はエスケープしてくれるのでこちらを使いましょう。
配列も

//公式
$query = DB::query("SELECT * FROM users WHERE username in :name")->param('name', ['hoge','fuga'])->execute();
//SELECT * FROM users WHERE username in ('hoge','fuga') ←生成Query

としてくれます。
しかしクエリビルダ自体がSQLの機能をすべて網羅しているわけではありません。
そのため難しいQueryが必要の際につまづきます。
そうなると上記のようにDB::query()とバインディングで直接SQLを記述することが多いと思います。
それだとwhere()のように柔軟にWHERE句を付け替えるのは難しくなります。
そして結果的にソースが煩雑になりがちです。
そこでこちらのブログが参考になります。

QueryBuilderで小難しいSELECT文を書くためのノウハウ #FuelPHPAdvent2012 - Dazing days

ただこちらで4.where句の右辺にMySQL関数を使いたい時のノウハウに

//  WHERE DATE(r.`rental_dttm`) >= ADDDATE( CURDATE(), INTERVAL -30 DAY ) = '1' ←生成Query
$query->where('DATE(r."rental_dttm") >= ADDDATE( CURDATE(), INTERVAL -30 DAY )', '=', true);

とあります。
これは素直に

//  WHERE DATE(r.`rental_dttm`) >= ADDDATE( CURDATE(), INTERVAL -30 DAY ) ←生成Query
$query->where('DATE(r."rental_dttm")', '>=', DB::expr("ADDDATE( CURDATE(), INTERVAL -30 DAY )"));
で問題ありません。
実際に実行されるQueryが想定通りのSimpleな形になるので運用者がクエリログを見た時も安心です。
それと生成したクエリは

$query = DB::query("SELECT * FROM users WHERE username = :name")->param(':name', 'value');
var_dump($query->compile());

で確認することが出来ます。
上記の例だと出力された:nameが'value'に置き換わって出力されます。

と以上になりますがDB接続はアプリ開発に必須です。
セキュリティと利便性を上手くとってスムーズに開発していきたいですね。

---チラシの裏---
クエリビルダのソースを含めFuelPHPのCoreのDB周りのソースを読みました。
綺麗で非常に読みやすくいい勉強になりました。
OSSはドキュメントになっていない隠し機能があることが多いので興味がある方は是非読んでみてください。

0 件のコメント:

コメントを投稿