多くの情報を条件絞り込みしてデータを取り出し一覧表示しようという仕組みを作るとします。

例えばユーザーリストを作るとして、ANDとORを使って条件にする項目は以下のようなものがあるとします。

年齢 → 20から29などの幅設定があり、さらにminとmaxの片方条件も可能
住んだことある場所 → 都道府県を複数選択可能
性別 → 男性、女性の二択

これをfind()に設定するwhereをconditionsに設定する場合、配列で組み合わせていくのですが、andとorの代入方法が意外と色々と面白くできたので記録として残します。

getで値を取得

$query_data = $this->request->getQuery();

キーにandの連想配列を作っておく

$conditions['and'] = null;

年齢の幅を設定

// min設定があれば追加
if(!empty($query_data['age_l'])) $conditions['and'][] = ['age_l >=' => $query_data['age_l']];

// max設定があれば追加
if(!empty($query_data['age_h'])) $conditions['and'][] = ['age_h <=' => $query_data['age_h']];

選択した都道府県分繰り返す

foreach ($pref as $value) {
  $or[] = ['pref Like' => '%'.$value.'%'];
}
$conditions['and'][] = ['or' => $or];
$this->Model->find()->where($conditions);

結果

// 文字は例としています
SELECT Model.id AS `Model__id` FROM model Model WHERE (people = `男性` AND age >= 20 AND age <= 29 AND (pref like `%東京%` OR pref like `%大阪%` OR pref like `%福岡%`))

ちゃんとandで都道府県分は括弧で囲みorを生成しています。最初のキーをandにして、そこにどんどん追加していくだけでいいんですね。しかも、andの追加なく、orの分だけ追加すると、andは消えてorのみのsql文を生成し実行してくれます。便利。