選択肢をチェックボックスでいくつか設置し、選択したものを取得してDBに検索かけるというプログラムを構築したいと思います。

結構面倒だったので記録に残します。

まずはビュー側から。

 

<?php
// viewファイル内
$checkbox = [
  "val01","val02","val03","val04","val05","val06",
];
?>
<?php foreach ($checkbox as $value): ?>
  <label><input type="checkbox" name="val[]" value="<?php echo $value; ?>" <?php if(in_array($value, $checked)) echo "checked"; ?>> <?php echo $value; ?></label>
<?php endforeach; ?>

 

$checkedは、コントローラー側でPOSTまたはGETで取得した値を配列型変数にして$this->setで代入してビューに渡したものです。そして、in_array()で$checkedに$valueが含まれている場合、checkedを出力するということで、選択済みの状態のチェックボックスを作ります。

 

<?php
// Controller側
$vals = $this->request->getQuery('val'); // 空の場合、NULLが入る
if (!empty($vals)) {
  $val_ary = []; // チェックボックスの値の検索用
  foreach ($vals as $value) {
    // DBのwhere文を追加する用
    $val_ary[] = ['checkbox LIKE' => '%' . $value . '%'];
  }
  $query->where(['OR' => $val_ary]);
}

$results = $this->paginate($query, [
  'limit' => 10, // 1ページあたりの表示件数
]);

$this->set(compact('results'));
$this->set('checked', $vals);
?>

 

これでDBにはチェックボックスで複数チェックした場合、Whereで指定したカラムのデータをORで検索して、一つでもヒットすればデータを取得する機能ができました。

ここではORにしてますが、絞り込みにする場合は、ANDで検索することにより複数の値が該当する場合という形にできます。

ただちょっと驚いたことがありました。

クエリーにORからANDにすれば良いのですが、ORのところに入れる配列のデータに間違って一つカッコを追加したところ、それもANDで検索するようになってました。

 

<?php
$query->where(['OR' => $val_ary]); // OR検索
$query->where(['OR' => [$val_ary]]); // AND検索
?>

 

不思議な現象でした。

もっと効率がよい方法もあるんでしょうけど、実はChatGPTを利用して検索機能のプログラムを聞いてみたところ、すべて上手くいかないソースばかりが紹介されてしまい、結局は自分で解決する内容を出した結果がこれという感じです。

そのことについては別でお話したいと思います。

ひとまずは結果も出たのでこれでいこうかと。