如何使用 mysqli 预准备语句绑定 N 个参数


How to bind N number of parameters using mysqli prepared statements?

在旧的mysql代码中,我在下面有一个查询,它运行良好,如下所示:

$questioncontent = (isset($_GET['questioncontent'])) ? $_GET['questioncontent'] : '';
$searchquestion = $questioncontent;
$terms = explode(" ", $searchquestion);
$questionquery = "
SELECT q.QuestionId, q.QuestionContent, o.OptionType, an.Answer, r.ReplyType, 
  FROM Answer an 
  INNER JOIN Question q ON q.AnswerId = an.AnswerId
  JOIN Reply r ON q.ReplyId = r.ReplyId 
  JOIN Option_Table o ON q.OptionId = o.OptionId 
                 WHERE ";
    foreach ($terms as $each) {     
        $i++;         
        if ($i == 1){         
            $questionquery .= "q.QuestionContent LIKE `%$each%` ";     
            } else {         
                $questionquery .= "OR q.QuestionContent LIKE `%$each%` ";    
                 } 
                 }  
                 $questionquery .= "GROUP BY q.QuestionId, q.SessionId ORDER BY "; $i = 0; foreach ($terms as $each) {     
                     $i++;      
        if ($i != 1)         
        $questionquery .= "+";     
        $questionquery .= "IF(q.QuestionContent LIKE `%$each%` ,1,0)"; 
        } 
        $questionquery .= " DESC ";

但是由于旧的mysql正在消失,人们说使用PDO或mysqli(由于我目前获得的php版本而无法使用PDO),我尝试将代码更改为mysqli,但这给我带来了问题。在下面的代码中,我省略了bind_params命令,我的问题是如何在下面的查询中绑定参数?它需要能够绑定多个$each,因为用户能够键入多个术语,并且每个$each都被归类为一个术语。

以下是同一查询的当前 mysqli 代码:

     $questioncontent = (isset($_GET['questioncontent'])) ? $_GET['questioncontent'] : '';
        $searchquestion = $questioncontent;
        $terms = explode(" ", $searchquestion);
        $questionquery = "
        SELECT q.QuestionId, q.QuestionContent, o.OptionType, an.Answer, r.ReplyType, 
          FROM Answer an 
          INNER JOIN Question q ON q.AnswerId = an.AnswerId
          JOIN Reply r ON q.ReplyId = r.ReplyId 
          JOIN Option_Table o ON q.OptionId = o.OptionId 
                         WHERE ";
    foreach ($terms as $each) {     
                $i++;         
                if ($i == 1){         
  $questionquery .= "q.QuestionContent LIKE ? ";     
                    } else {         
  $questionquery .= "OR q.QuestionContent LIKE ? ";    
                         } 
                         }  
 $questionquery .= "GROUP BY q.QuestionId, q.SessionId ORDER BY "; $i = 0; foreach ($terms as $each) {     
                             $i++;      
                if ($i != 1)         
                $questionquery .= "+";     
                $questionquery .= "IF(q.QuestionContent LIKE ? ,1,0)"; 
                } 
                $questionquery .= " DESC ";

            $stmt=$mysqli->prepare($questionquery);      
            $stmt->execute();
            $stmt->bind_result($dbQuestionId,$dbQuestionContent,$dbOptionType,$dbAnswer,$dbReplyType); 
            $questionnum = $stmt->num_rows();

看看这篇SO帖子,它讨论了call_user_func_array与bind_param()一起使用。

从 mysqli_stmt_bind_param 年的 PHP 文档中,它说以下内容...

注意:

结合使用 mysqli_stmt_bind_param() 时必须小心 与 call_user_func_array()。请注意,mysqli_stmt_bind_param() 要求通过引用传递参数,而 call_user_func_array() 可以接受变量列表作为参数 可以表示引用或值。

你会想要使用这样的东西

call_user_func_array(array($stmt, 'bind_param'), $terms);

由您来确保 SQL 字符串$stmt中出现正确数量的?字符。

[编辑]

这是一个工作示例

// user entered search strings
$user_terms = array("a", "b", "c");
// append your wildcard "%" to all elements. you must use "&" reference on &$value
foreach ($user_terms as &$value) {
    $value = '%'.$value.'%';
}
$types = "";
for($i = 0; $i<sizeof($user_terms); $i++) {
    $types .= "s";
}
$terms = array_merge( array($types), $user_terms);
// the array $terms now contains: { "sss", "%a%", "%b%", "%c%" }
$sql = "SELECT ... ?,?,?"    // edit your sql here
$stmt = $mysqli->prepare($sql)
call_user_func_array(array($stmt, 'bind_param'), $terms);