1

私が持っている Mysqli コードは、成功した検索の結果を表示していません。これはMYSQLでテストしていたので、クエリはステートメントに関して正しいです。しかし、mysqli を使用しようとすると、検索が成功した後に結果が表示されないようです。私は何を間違っていますか?エラー報告を行ってもエラーは発生せず、クエリにスペルミスもありません。クエリがループの外にある必要があるためか、パラメーターを正しくバインドしていないか、そのようなものかどうかはわかりませんが、コードは古いmysqlコードで機能していましたが、mysqliでは機能しません(できません)私のPHPのバージョンのためにPDOを使用してください)

お申し込みURLはこちらです。「AAD」と入力すると、「AAD」という用語を含むデータベースに5行あるため、実際には結果が見つからないはずですが、結果が見つからないと表示されます

以下はフォームコードです。

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

以下は、mysqli コード全体とそのコメントです。

//Get terms entered in the textbox    
$questioncontent = (isset($_GET['questioncontent'])) ? $_GET['questioncontent'] : '';

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

//Start of query      
$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 ";

$i=0;
//loop through each term
foreach ($terms as &$each) { 
$each = '%'.$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 ? ";    
} 
}  
//group terms by terms entered in chronilogical order                
$questionquery .= "GROUP BY q.QuestionId, q.SessionId ORDER BY "; $i = 0; foreach ($terms as $each) {     
$i++;      

//if multiple terms, then display results that contains all terms first, then start displaying other results by knocking off 1 term at a time                    
if ($i != 1)         
$questionquery .= "+";     
$questionquery .= "IF(q.QuestionContent LIKE ? ,1,0)"; 
} 

$questionquery .= " DESC "; 

//bind the parameters by the amount of terms there are      
$types = "";
for($i = 0; $i<sizeof($terms); $i++) {
$types .= "s";
}

//merge the parameters and the terms    
$eachterms = array_merge( array($types), $terms);

//prepare quert    
$stmt=$mysqli->prepare($questionquery);
//in array call all the parameters and its terms      
call_user_func_array(array($stmt, 'bind_param'), $eachterms);
//execute terms 
$stmt->execute();
//bind the result
$stmt->bind_result($dbQuestionContent); 


//display the results of the successful search
$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;

}
4

2 に答える 2

1

このエラー メッセージの理由は、それがMySQLi_Stmtオブジェクト$stmtではないことです。その理由は、 に渡すステートメントの構文エラーです。$mysqli->prepare

"… q.QuestionContent LIKE '%'.$each.'%' "

これにより、次のような結果になります。

… q.QuestionContent LIKE '%'.<value of each>.'%'

ここでの問題:.は MySQL の文字列連結演算子ではなく ( を使用する必要があります+)、$eachおそらく適切に引用された MySQL 文字列宣言ではないため、有効な式になります。

それとは別に、データをステートメントに直接挿入すると、準備済みステートメントを使用する主な理由の 1 つが損なわれます。データがコマンドとして誤って解釈されないように、コマンドとデータを互いに分離するためです (つまり、SQL インジェクション)。

したがって、文字列値を直接挿入する代わりに、?代わりに a を配置します。次に、ステートメントを準備し、パラメーターをバインドして実行します。

$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 ";

$paramTypes = '';
$params = array();
$i=0;
//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 ? ";
    }
    $params[] = "%$each%";
    $paramTypes .= "s";
}  
//group terms by terms entered in chronilogical order                
$questionquery .= "GROUP BY q.QuestionId, q.SessionId ORDER BY ";
$i = 0;
foreach ($terms as $each) {
    $i++;
    //if multiple terms, then display results that contains all terms first, then start displaying other results by knocking off 1 term at a time
    if ($i != 1) $questionquery .= "+";
    $questionquery .= "IF(q.QuestionContent LIKE ? ,1,0)";
    $params[] = "%$each%";
    $paramTypes .= "s"
}
$questionquery .= " DESC ";

//prepare query
$stmt=$mysqli->prepare($questionquery);
//bind parameters
call_user_func_array(array($stmt, 'bind_params'), array_merge(array($paramTypes), $params));
//execute query
$stmt->execute();

繰り返しになりますが、全文検索を実際に確認する必要があります。この手動のクエリ構築全体が時代遅れになる可能性があります。

… WHERE MATCH (q.QuestionContent) AGAINST ("search terms" IN NATURAL LANGUAGE MODE)
于 2012-06-24T14:14:21.200 に答える
0

ステートメントを変更します。

$questionquery .= "IF(q.QuestionContent LIKE '%'.$each.'%' ,1,0)";
$questionquery .= "q.QuestionContent LIKE '%'.$each.'%' ";
$questionquery .= "OR q.QuestionContent LIKE '%'.$each.'%' ";

これに(それぞれ):

$questionquery .= "IF(q.QuestionContent LIKE '%" . $each . "%' ,1,0)";
$questionquery .= "q.QuestionContent LIKE '%" . $each . "%' ";
$questionquery .= "OR q.QuestionContent LIKE '%" . $each . "%' ";

また、変数に対してこれを行う必要があると思います$stmt

$stmt = $mysqli->stmt_init();
$stmt->prepare($questionquery);
//execute query
$stmt->execute();
于 2012-06-24T13:34:27.007 に答える