-1

これは奇妙ですが、何が起こっているのかを説明します。

SQL では、LIKE ステートメントを使用してデータベース内の 2 つの用語 (AAA、AAB) を見つけたいとします。これらの用語の結果を見つけることができるクエリは次のとおりです。

SELECT q.QuestionContent
FROM Question q
WHERE q.QuestionContent LIKE '%AAA%'
OR q.QuestionContent LIKE '%AAB%'
GROUP BY q.QuestionId, q.SessionId
ORDER BY IF( q.QuestionContent LIKE '%AAA%', 1, 0 ) , IF( q.QuestionContent LIKE '%AAB%', 1, 0 )

だから私はSQLが機能することを知っています。だから私がしたいのは、このクエリを MYSQLi に含めることです。唯一の違いは、ユーザーが検索ボックスに用語を入力して、検索ボックスを送信できることです。したがって、ユーザーは 1 用語、2 用語、3 用語など、任意の数の用語を入力できます。

以下は、これを行うために作成した MYSQLi コードです。

        <form action="previousquestions.php" method="get">
              <p>Search: <input type="text" name="questioncontent" value="<?php echo $questioncontent; ?>" onchange="return trim(this)" /></p>
              <p><input id="searchquestion" name="searchQuestion" type="submit" value="Search" /></p>
              </form>


        <?php 

        if (isset($_GET['searchQuestion'])) {

        $searchquestion = $questioncontent;
        $terms = explode(" ", $searchquestion);

        $questionquery = "SELECT q.QuestionContent FROM Question q WHERE ";

        $i=0;

        $whereArray = array();
        $orderByArray = array();
        $orderBySQL = "";
        $paramString = "";

        //loop through each term
        foreach ($terms as &$each) {
            $i++;
            //if only 1 term entered then perform this LIKE statement
            if ($i == 1){
                $questionquery .= "q.QuestionContent LIKE ? ";
            } else {
                //If more than 1 term then add an OR statement
                $questionquery .= "OR q.QuestionContent LIKE ? ";
                $orderBySQL .= ",";
            }

            $orderBySQL .= "IF(q.QuestionContent LIKE ? ,1,0)"; 

            $whereArray[] = "%" . $each . "%";
            $orderByArray[] = "%" . $each . "%"; 

            $paramString .= "ss";
        }  

        $questionquery .= "GROUP BY q.QuestionId, q.SessionId ORDER BY " . $orderBySQL; 
        $stmt=$mysqli->prepare($questionquery)or die($mysqli->error); 
function makeValuesReferenced(&$arr){ 
    $refs = array(); 
    foreach($arr as $key => $value) 
        $refs[$key] = &$arr[$key]; 
    return $refs; 

}

call_user_func_array(array($stmt, 'bind_param'), makeValuesReferenced(array_merge((array)$paramString,$whereArray, $orderByArray)));

    $stmt->execute();
    $stmt->bind_result($dbQuestionContent); 
    $questionnum = $stmt->num_rows();
    echo $questionquery;
    echo $paramString;

//OUTPUT RECORDS

        if (empty($questioncontent)){
    echo "Please enter in a phrase in the text box in able to search for a question";
}

        else if($questionnum ==0){
    echo "<p>Sorry, No Questions were found from this Search</p>";
    }
    else{

            $output = "";
    $output .= "
        <table border='1' id='resulttbl'>
          <tr>
          <th class='questionth'>Question</th>
          </tr>
    ";
            while ($stmt->fetch()) {
    $output .= "
          <tr>
          <td class='questiontd'>{$dbQuestionContent['QuestionContent']}</td>
          </tr>";
            }
            $output .= "        </table>";

            echo $output;

      }
}
            ?>

問題は、ユーザーが正しい用語を入力しても、それらの用語を含むデータベースのレコードが表示されないことです。何も出力しません。これは意味がありません。検索ボックスに「AAA AAB」という 2 つの用語を入力すると、クエリとパラメーターをエコーすると、次のように出力されるため、正しいように見えます。

クエリ出力:

SELECT q.QuestionContent FROM Question q WHERE q.QuestionContent LIKE ? OR q.QuestionContent LIKE ? GROUP BY q.QuestionId, q.SessionId ORDER BY IF(q.QuestionContent LIKE ? ,1,0),IF(q.QuestionContent LIKE ? ,1,0)

パラメータ出力:

ssss

私の質問は、クエリが正しく、パラメーターの数が正しい場合、検索が成功してもレコードが表示されない原因は何ですか?

現時点では、ここにある警告が表示されます。

警告: mysqli_stmt::bind_param() [mysqli-stmt.bind-param]: Number of elements in type definition string does not match number of bind variables in ... 87 行目

この警告を修正するには何が必要ですか?

4

2 に答える 2

1

また、コードを見ると、いくつかの論理エラーがあります。

1)

$searchquestion = $questioncontent;

する必要があります

$searchquestion = $_GET['questioncontent'];

2)

if (empty($questioncontent)){

する必要があります

if (empty($searchquestion)){

3)

<td class='questiontd'>{$dbQuestionContent['QuestionContent']}</td>

する必要があります

<td class='questiontd'>$dbQuestionContent</td>
于 2012-06-28T04:44:37.933 に答える
1

このエラーが発生する理由は、1つの要素のみを渡すためです。配列。

$stmt->bind_param($paramString, array_merge($whereArray, $orderByArray));

それがどのように見える必要があるかはこれです

$stmt->bind_param($paramString, $param1, $param2, $param3 ...);

$paramStringのsごとに個別のパラメータが必要です。量が変動する可能性があるため、これは明らかに少し難しいです。だから交換する

$stmt->bind_param($paramString, );

$ref = array_merge((array)$paramString, $whereArray, $orderByArray);
call_user_func_array(array($stmt, 'bind_param'), makeValuesReferenced($ref));

function makeValuesReferenced(&$arr){ 
    $refs = array(); 
    foreach($arr as $key => $value) 
        $refs[$key] = &$arr[$key]; 
    return $refs; 

}

私はそれをテストしていないので、それが機能するかどうかわからない。PHP5.3.1の参照渡しの問題から解決策を得ました

于 2012-06-28T02:59:57.103 に答える