Zend_FrameworkのZend_DB_Select、これには順次処理でwhere文を生成する仕組みがあるのですが、単純な連結には便利でも複合条件の連結が使いにくくてタマラン、ということでhelperクラスを作ったのですよ。
Zend_DB_Selectのwhereメソッドの例
<?php $query = $tbl->select(); $query->where('human=?', 1); $query->where('name like ?', 'イン%'); :where文 (human=1) and (name like `イン%`) $query = $tbl->select(); $query->where('human=?', 1); $query->where('(' . $db->quoteInto('name like ?', 'イン%') . ' or ' . $db->quoteInto('name like ?', 'イカ%') . ' or ' . $db->quoteInto('name = ?', 'キュアピース') . ')'); :where文 (human=1) and ((name like `イン%`) or (name like `イカ%`) or (name = `キュアピース`))
ヘルパークラス(抜粋)。
<?php class sqlHelper { private $_whereArray = array(); public function __construct() { $this->resetWhere(); } /* * 順次処理でwhere文の条件式を連結 * (条件を連結する処理のみ行う。条件のクオート処理は行わない) * ここでの連結は同じレベルでのみ行う。グループ化した条件とor/andをしたい場合は、事前にmakeWhereで条件を連結して、 * 連結結果をaddOr/addAndで追加する。 * * (ex.) * * (a=1) or (a=2) or (b=3) を生成 : * resetWhere(); * addOr('a=1'); * addOr('a=2'); * addOr('b=3'); * 結果 = makeWhere(); * * ((a=1) or (a=2)) and (b=3) を生成 : * resetWhere(); * addOr('a=1'); * addOr('a=2'); * s = makeWhere(); * * resetWhere(); * addOr(s); // 注:リセット後の1回目はor/andどっちでも同じ * addAnd('b=3'); * 結果 = makeWhere(); * */ /** * where条件生成をリセット * */ public function resetWhere() { $this->_whereArray = array(); } /** * 指定した値をor条件として連結 * * @param string $value */ public function addOr($value) { $this->_whereArray[] = array('cond' => 'or', 'value' => $value); } /** * 指定した値をand条件として連結 * * @param string $value */ public function addAnd($value) { $this->_whereArray[] = array('cond' => 'and', 'value' => $value); } /** * addOr / addAndで作成した条件からwhere条件を生成 * * @return string */ public function makeWhere() { if (count($this->_whereArray) == 0) { return ''; } $res = ''; foreach ($this->_whereArray as $item) { if ($res == '') { $res = '(' . $item['value'] . ')'; } else { $res = $res . ' ' . $item['cond'] . ' (' . $item['value'] . ')'; } } return $res; } }
で、こんな感じで連結。
<?php $query = $tbl->select(); $query->where('human=?', 1); $sql = new sqlHelper; $sql->addOr($db->quoteInto('name like ?', 'イカ%')); $sql->addOr($db->quoteInto('name like ?', 'イン%')); $sql->addOr($db->quoteInto('name = ?', 'キュアピース')); $query->where($sql->makeWhere()); :where文 (human=1) and ((name like `イカ%`) or (name like `イン%`) or (name = `キュアピース`))
‥‥、ただコレ、連結条件を生成した結果、条件が無かった場合には''を返すのですが、それをwhere()に突っ込むとご丁寧に''のまま条件を生成してくれてMySQLまで渡った後に例外になるのですよ。
makeWhereを使う毎に毎回毎回''チェックかけるのも面倒だし、where()にnullを渡したら無視してくれないかな?そうしたら戻り値をnullに変更するだけで簡単なのにとテストしたら‥‥、ご丁寧にnullのまま条件を生成してくれて(ry orz
事前チェックは出来ますが、毎度こんな判定するのは超面倒。
<?php if ($sql->makeWhere() <> '') { $query->where($sql->makeWhere()); }