あるテーブル(table)の文字列(name)の中に、"AAA"と"BBB"の双方が含まれているレコードを探したい。
$sql = "SELECT name FROM table WHERE name LIKE ? AND name LIKE ?";
$stmt = $pdo->prepare($sql);
$key='%AAA%';
$stmt->bindParam( 1, $key, PDO::PARAM_STR);
$key='%BBB%';
$stmt->bindParam( 2, $key, PDO::PARAM_STR);
$stmt->execute();
while( $row = $stmt->fetch(PDO::FETCH_ASSOC) ) {
echo $row["name"];
echo "<br>";
}
これが想定した戻りにならない。
WHERE 区の AND が OR になったような値を返す。(厳密にはちょっと違う)
で、色々調べていったら、
$key='%AAA%';
$stmt->bindParam( 1, $key, PDO::PARAM_STR);
$key2='%BBB%';
$stmt->bindParam( 2, $key2, PDO::PARAM_STR);
と、異なる変数名(key2)にしたら想定通りの動きになった。
説明のために AAA と BBB をバラして書いたけど、本当は検索文字は Array に入っているなので、ループで回して処理したいのに、同じ変数だと想定した値が戻らない。
現象だけわかっていて、理由はよくわからないのですが、困ってます(笑)。
↓
コメントで情報をいただき、解決しました。
bindParam の第二パラメータは参照渡しなので、使いまわすと上書きされて、
SELECT name FROM table WHERE name LIKE '%AAA%' AND name LIKE '%BBB%'
のつもりが
SELECT name FROM table WHERE name LIKE '%BBB%' AND name LIKE '%BBB%'
と、なっていたようです。
ループ内で使うときは、bindParam の第二パラメータに Array とすることで、想定通りの動作なりました。
例えば、こんな感じ。
for( $i=0 ; $i < count( $keywords ) ; $i++ ) {
$stmt->bindParam( $i, $keywords[$i], PDO::PARAM_STR);
}