2016-04-29 102 views
3

我在php中使用PDO。但是,当我的查询有任何关键字像“'”意味着连字符它打破并通过一个错误。 我准备通过互联网,并找到解决方案绑定与查询参数,它工作正常。 但问题是我在循环中构建查询,我无法在循环内绑定参数。 这是代码,我用空间拆分数组,并对每个关键字运行查询。 前3个单词将只有像查询和更多然后3个单词我正在使用循环来连接所有数组元素和相同的多于6个单词我正在使用MATCH查询。 有没有什么办法来逃避这个连字符,或者我们如何在我的情况下使用循环绑定参数?在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'=> $ keyword))''中引用''。把东西添加到字符串很容易,如果你同时向你的数组添加东西,它们将保持同步。 – tadman

回答

2

构建动态查询时,需要将查询中那些静态的部分与动态的部分分开。

你可以看到下面的代码是静态的。

"SELECT * FROM faq "; 

其余的代码是动态的。过滤记录时,使用WHERE子句,并使用AND运算符来根据多个条件过滤记录。如果第一个条件和第二个条件都为真,则AND运算符显示记录。如果第一个条件或第二个条件为真,则OR运算符显示记录。所以在使用,但之后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来应用滤波器和未命名的参数吗?

尽可能使用“懒惰”绑定 - 将数据传递到执行会显着缩短您的代码。见PDO info

//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

“尽可能使用”懒惰“绑定”是! – miken32

+0

这正是我一直在寻找的。 – Bilal