4727


失礼します。

mysqlとphpを使ったOR検索のプログラムを作っています。  
複数ワードで検索をした時に、

[code]

    SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
    
[/code]

という例外がスローされました。  
調べてみたところ、プレースホルダとパラメータの数が合っていない？という意味なのかと思ったのですがコードを見なおしても自分では理解できませんでした。

以下がコードです。(一部を抜粋)

[code]

    //OR検索時
                elseif($count > 1){
                    $stmt = $pdo->prepare($query);
                    for($i=0; $i<$count; $i++){ //検索ワードの数だけ繰り返す
                        $keyword2[$i] = "'%".$keyword[$i]."%'"; //検索ワード1つ1つを%検索文字%にする
                        $holder = ':keyword'.$i;    //ホルダー用
                        $stmt->bindParam(':holder',$keyword2[$i],PDO::PARAM_STR);
                    }
                    $stmt->execute();
                    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
                }
    
[/code]

どう直したらよいのでしょうか？  
全コードが必要でしたら書き直します。

よろしくお願いします。

追記：$queryの中身です。

[code]

    $query = 'SELECT * FROM goods WHERE ';  //クエリ前半
    $sql ="";
    if($data){
        $count = 1; //カウントを１にしておく
        //全角スペースはmb_convert_kana()関数で半角スペースに変換
        $datalist = mb_convert_kana($data, 's','UTF-8');
        //複数キーワードでの検索
        //if(stristr($datalist," ")){
            //検索ワードをスペースで分割して配列に格納
            $keyword = explode(" ",$datalist);
    
            //print_r ($keyword);
            //配列の数を数える
            $count = count($keyword);
            print $count;
            //空スペースで区切られた数によってSQL文を組み立てる
            for($i=0; $i<$count; $i++){//配列の数だけ繰り返す
                if($i!="0"){
                    $sql = $sql." OR ";
                }
                $sql = $sql."name LIKE :keyword";
            }
    
[/code]


CC BY-SA 3.0
2015-01-17T05:20:52.930
4725
2015-01-17T06:40:57.277
2015-01-17T05:34:38.513
5985
5985
question
php mysql
スローされた例外の原因と対処方法が分からない


ソースコード上に3か所誤りがあります。

  1. `$keyword2[$i]`の先頭と末尾に引用符が付いている
  2. バインドする変数名が全て`':holder'`になっている(`$holder`を使用していない)
  3. `$sql = $sql."name LIKE :keyword";`に`$i`がない

例外が発生している直接の原因は2.で設定している変数名`:holder`と、3.で実際に記述されている変数名`:keyword`が食い違っているためと思われます。両方を`:keyword0`,
`:keyword1`, `:keyword2`…となるように修正しなくてはなりません。

上記を直した場合も、1.でバインド変数に指定されている値が誤っているので意図した検索結果にはならないでしょう。SQL文に`'%abc%'`と書いた場合は`%abc%`という文字列を表しますが、PHP上で設定しているのは`'%abc%'`という値の文字列ですので先頭と末尾に引用符があるnameしか条件に合致しません。

逆に言うと`$keyword[$i]`の値に引用符や他の演算子が含まれていたとしても[SQLの意味が変わる](https://ja.wikipedia.org/wiki/SQL%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)ことはありません。


CC BY-SA 3.0
2015-01-17T05:30:43.290
4727
2015-01-17T06:40:57.277
2015-01-17T06:40:57.277
5750
5750
4725
answer