ユーザーがさまざまな種類の情報を含めることができるデータベースに、かなり基本的な検索エンジンを実装しようとしています。検索自体は、結果が常に 3 つの列にマージされる 2 つのユニオン選択で構成されます。
ただし、返されるデータは別のテーブルからフェッチされています。
各クエリはマッチメイキングに $term を使用し、準備済みパラメーターとして ":term" にバインドしました。
さて、マニュアルには次のように書かれています。
PDOStatement::execute() を呼び出すときに、ステートメントに渡す値ごとに一意のパラメーター マーカーを含める必要があります。準備済みステートメントで、同じ名前の名前付きパラメーター マーカーを 2 回使用することはできません。
各 :term パラメータを :termX (x for term = n++) に置き換える代わりに、より良い解決策が必要だと思いましたか?
それとも X 個の :termX をバインドする必要がありますか?
これに私のソリューションを投稿編集:
$query = "SELECT ... FROM table WHERE name LIKE :term OR number LIKE :term";
$term = "hello world";
$termX = 0;
$query = preg_replace_callback("/\:term/", function ($matches) use (&$termX) { $termX++; return $matches[0] . ($termX - 1); }, $query);
$pdo->prepare($query);
for ($i = 0; $i < $termX; $i++)
$pdo->bindValue(":term$i", "%$term%", PDO::PARAM_STR);
よし、これがサンプルだ。sqlfiddle を使用する時間はありませんが、必要に応じて後で追加します。
(
SELECT
t1.`name` AS resultText
FROM table1 AS t1
WHERE
t1.parent = :userID
AND
(
t1.`name` LIKE :term
OR
t1.`number` LIKE :term
AND
t1.`status` = :flagStatus
)
)
UNION
(
SELECT
t2.`name` AS resultText
FROM table2 AS t2
WHERE
t2.parent = :userParentID
AND
(
t2.`name` LIKE :term
OR
t2.`ticket` LIKE :term
AND
t1.`state` = :flagTicket
)
)