2016-04-29 9 views
3

私はPHPでPDOを使用しています。しかし、クエリに "''のようなキーワードがあると、ハイフンが壊れてエラーが発生します。 私はインターネット上で準備ができており、クエリでパラメータをバインドするソリューションを見つけても問題ありません。 しかし、問題は私がループ内のクエリを構築していると私はループ内のパラメータをバインドすることができません。 ここでは、配列をスペースで分割してすべてのキーワードに対してクエリを実行するコードを示します。 最初の3つの単語は同じようなクエリと3つ以上の単語を持っています。私はすべての配列要素を連結するためにループを使用しています。 ハイフンをエスケープする方法はありますか、私の場合はループを使用してパラメータをバインドする方法はありますか?PHPでPDOでパラメータをバインドする

 $keyword = ($_POST['keyword']); 
     $keyword_array = split(' ',$keyword); 

     /* Query For first Three Words */ 
     if(count($keyword_array)<=3){ 
        $sql = "SELECT * FROM faq WHERE question LIKE '%$keyword%' limit 14"; 
     } 
     /* Query through all array when words are greater then 3 */ 
     if(count($keyword_array)< 6){ 
      $sql = "SELECT * FROM faq WHERE question "; 
       for($i = 0 ; $i<count($keyword_array); $i++){ 

       if($i==0){ 
           $sql.=" LIKE '%$keyword_array[$i]%'"; 
       }else{ 
           $sql.=" or question LIKE '%$keyword_array[$i]%' "; 
       } 
      } 
         $sql .= " ORDER BY question ASC LIMIT 0, 8"; 
     } 
     /* Appl FULL TEXT in natual language mode once we have enough phrase */ 
     else if(count($keyword_array)>=6){ 
       $sql = "SELECT * FROM faq WHERE "; 
        for($i = 0 ; $i<count($keyword_array); $i++){ 

        if($i==0){ 
            $sql.=" MATCH (answer) AGAINST ('$keyword_array[$i]' in natural language mode) "; 
        }else{ 
            $sql.=" or MATCH(answer) AGAINST('$keyword_array[$i]' in natural language mode) "; 
        } 
      } 
       $sql .= " limit 0,5"; 
     } 


      $execute_faq_query = $conn->query($sql); 
      $execute_faq_query->setFetchMode(PDO::FETCH_ASSOC); 

      while ($list = $execute_faq_query->fetch()){ 
} 
+0

ループは、SQLステートメントを作成し、単一のSQLクエリを実行する必要があります。 –

+0

はい、私はそれを試してみましたが、私はPDOで新しくなっているので問題が発生しています。 – Bilal

+0

PDOは ':keyword'のような名前付きプレースホルダをサポートしています。このプレースホルダは' execute(array( ':キーワード' => $ keyword))中に参照できます。文字列に物を追加するのは簡単ですし、配列に物事を追加すると同時にそれらは同期していきます。 – tadman

答えて

2

ダイナミッククエリを構築するときは、クエリの静的な部分と動的な部分を分離する必要があります。

次のコードは静的であることがわかります。

"SELECT * FROM faq "; 

残りのコードは動的です。レコードをフィルタリングするときは、WHERE句が使用され、AND &のOR演算子が複数の条件に基づいてレコードをフィルタリングするために使用されます。 AND演算子は、第1の条件と第2の条件の両方が真である場合にレコードを表示します。 OR演算子は、第1の条件または第2の条件のいずれかが真である場合にレコードを表示します。フィルタが適用され、変更されたままになるまでそう使用されるが、その後ANDまたはORを使用する必要がありますされて最初の条件のために(使用するか、またはあなたの例では)フィルタが変更されていない各フィルタ 注

// Static code 
sql = "SELECT * FROM `faq`" 
// Set initial condition to WHERE  
clause = "WHERE";  
if(!empty(filter)){ 
    Add clause to sql 
    Add condition to sql 
    change clause to OR or AND as required 
} 

リピート一度変更されました。 すべてのフィルタが処理された後、残りの静的コードが追加されます。

私はSwitch Caseを使用してフィルタと名前のないパラメータを適用しましたか?

可能であれば、「レイジー」バインディングを使用してください。データを実行に渡すと、コードが大幅に短縮されます。 を参照してください。

//Test $POST[] remove after testing 
$_POST['keyword'] ="one two three four five six"; 
$keyword = ($_POST['keyword']); 
$keyword_array = split(' ',$keyword); 
$words = count($keyword_array); 
echo $words; 
//You need an array to store parameters 
$paramArray =array(); 
//Initial clause 
$clause = "WHERE"; 
//Start with a basic stub 
$sql = "SELECT * FROM faq "; 
switch (true) { 
    case $words <= 3: 
     $sql .= " $clause question LIKE ?"; 
     $keyword = "%$keyword%"; 
     array_push($paramArray,$keyword); 
     $limit = " LIMIT 14"; 
     break; 

    case $words < 6: 
     for($i = 0 ; $i<count($keyword_array); $i++){ 
      $sql .= " $clause question LIKE ?"; 
      $keyword = "%$keyword_array[$i]%"; 
      array_push($paramArray,$keyword); 
      $clause = "OR"; 
      $limit = " ORDER BY question ASC LIMIT 0, 8"; 
     } 
     break; 

    case $words >=6: 
     $clause = ""; 
     for($i = 0 ; $i<count($keyword_array); $i++){ 
      $sql.=" $clause MATCH (answer) AGAINST (? in natural language mode) "; 
      array_push($paramArray,$keyword_array[$i]); 
      $clause = "OR"; 
      $limit = " limit 0,5"; 
     } 
     break; 
} 
//echo query and parameter array remove after testing 
echo $sql; 
echo "<br>"; 
print_r($paramArray); 

//Prepare and execute query 
$execute_faq_query = $conn->prepare($sql); 
$execute_faq_query->execute($paramArray); 
$execute_faq_query->setFetchMode(PDO::FETCH_ASSOC); 
while ($list = $execute_faq_query->fetch()){ 
} 
+0

"可能であれば"遅延バインディングを使用 "YES! – miken32

+0

これはまさに私が探していたものです。 – Bilal

関連する問題