【问题标题】:How to bind N number of parameters using mysqli prepared statements?如何使用mysqli准备好的语句绑定N个参数?
【发布时间】:2012-06-22 07:46:59
【问题描述】:

在旧的 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();

【问题讨论】:

    标签: php mysqli


    【解决方案1】:

    看看这个SO Post,它讨论了call_user_func_arraybind_param()的使用。

    来自PHP Docs on mysqli_stmt_bind_param 它说以下...

    注意:

    结合使用 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);
    

    【讨论】:

    • 我会试一试,但我猜代码行会是这样的:call_user_func_array( array ($stmt, 'bind_param'), $each); ?我还需要将 % 与 $each 连接起来,因为它是 LIKE 语句吗?会不会是这样call_user_func_array( array ($stmt, 'bind_param'), $each = '%' . $each . '%');
    • 好的,我试过这个:call_user_func_array( array ($stmt, 'bind_param'), $each = '%' . $each . '%'); 但如果我输入正确的术语,例如 'AAA',它无法找到旧 mysql 代码中的结果,它确实找到了结果跨度>
    • 用工作代码更新了答案。诀窍是确保 $types 变量与您的搜索 $user_terms 具有相同数量的 s 字符,这也必须与 $sql 中的 ? 字符数匹配
    猜你喜欢
    • 2011-06-22
    • 2020-12-11
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    相关资源
    最近更新 更多