LoginSignup
1
1

More than 5 years have passed since last update.

PHP で Mysql の戻りが想定と違う

Last updated at Posted at 2018-03-06

あるテーブル(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);
  }
1
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1