2013-04-06 218 views
0

我正在嘗試使用mysqli爲LIKE語句查詢和通配符運算符準備語句。經過調試後,在整個代碼中都會出現echo語句,我可以看到while語句沒有執行。你能看到我在這裏做錯了嗎?mysqli_fetch_array(),預處理語句和LIKE語句

這是我第一次問這個論壇,所以我很抱歉,如果這不是一個好問題,我花了6個小時試圖讓我的代碼的準備語句部分工作,我找不到解決我的問題的任何線索(例如How can I put the results of a MySQLi prepared statement into an associative array?)。我發現的兩個最接近的是:

Using wildcards in prepared statement - MySQLiCombine PHP prepared statments with LIKE

這裏是我的代碼的相關摘錄:

//set up and execute queries 
    $titleQuery = "SELECT keyframeurl, videoid, title, creationyear, sound, color, 
    duration, genre FROM openvideo WHERE title LIKE CONCAT ('%', ?, '%') 
    ORDER BY $order"; 

    if($stmt = mysqli_prepare($db, $titleQuery)){ 
     //bind parameters 
     mysqli_stmt_bind_param($stmt, 's', $trimmedTitleSearch); 
     //execute query 
     mysqli_stmt_execute($stmt); 
     //bind results 
     mysqli_stmt_bind_result($stmt, $keyframeurl, $videoid, $title, $year, $sound, 
     $color, $duration, $genre); 
     //store result so num rows can be counted 
     $result = mysqli_stmt_store_result($stmt); 
     //fetch results 
     while ($row = mysqli_fetch_array($result, MYSQL_ASSOC)) { 
      echo "<tr>"; 
       echo "<td><a href=\"".$row['keyframeurl']."\">".$row['videoid']."</a></td>"; 
       echo "<td>" . $row['title'] . "</td>"; 
       echo "<td>" . $row['year'] . "</td>"; 
       echo "<td>" . $row['sound'] . "</td>"; 
       echo "<td>" . $row['color'] . "</td>"; 
       echo "<td>" . $row['duration'] . "</td>"; 
       echo "<td>" . $row['genre'] . "</td>"; 
      echo "</tr>"; 
     } 
    } 
    else { 
    // Error 
    printf("Prepared Statement Error: %s\n", $db->error); 
    } 

感謝您的諮詢!

+2

我之前使用過MySQLi,但把它變成數組是一個很大的挑戰。如果你剛開始這個程序,我會建議學習PDO,因爲它使得數組和檢索信息比MySQLi容易得多。 MySQLi_STMT只是....不完整,感覺就像它被遺棄了一半。 – Rujikin 2013-04-06 03:15:03

+0

「我可以看到我的while語句沒有執行」 - 任何錯誤消息? – sectus 2013-04-06 03:27:23

+0

是的,這不是一個好問題。只是*看*代碼是不是要走的路。代碼必須是*運行*代替。你應該分開你的目標,不要一次全部完成。用事先準備好的語句對事情進行排序,然後進行LIKE或其他特定查詢。是的 - 如果你不想浪費你的時間,[**移動到PDO **](http://stackoverflow.com/tags/pdo/info),直到不會太晚 – 2013-04-06 03:39:54

回答

1

你混合2款獲取的結果。要麼使用醜陋的bind_result方式(然後使用fetch()然後獲取您的數據),要麼嘗試使用get_result() - 因此,您將可以使用fetch_array()(但不保證)。

無論如何,只要擺脫所有的混亂和使用PDO。

$titleQuery = "SELECT keyframeurl, videoid, title, creationyear, sound, color, 
duration, genre FROM openvideo WHERE title LIKE CONCAT ('%', ?, '%') 
ORDER BY $order"; 

$stmt = $pdo->prepare($titleQuery); 
$stmt->execute(array($trimmedTitleSearch)); 
$data = $stmt->fetchAll(); 

foreach ($data as $row) { 
    // the rest is the same as yours 

我希望你正確消毒你的$ order變量。最好的辦法是顯然它通過佔位補充,所以,你需要一個庫,允許它,SafeMysql例如:

$sql = "SELECT * FROM openvideo WHERE title LIKE CONCAT ?s ORDER BY ?n"; 
$data = $db->getAll($sql,"%$trimmedTitleSearch%", $order); 
foreach ($data as $row) { 
    // the rest is the same as yours 

注意的代碼量,並與生API的是負載要求你比較使用此刻

+0

'get_result'在挑選喜歡工作的地方很挑剔。與其他人相比,謝謝你提供了一個非常好的答案。 – Jon 2013-04-06 04:08:29

-1
  echo "<td>" . $row['color'] . "</td>"; 
      echo "<td>" . $row['duration'] . "</td>"; 
      echo "<td>" . $row['genre'] . "</td>"; 
     echo "</tr>";  while ($row = mysqli_fetch_array($stmt, MYSQL_ASSOC)) 

或者while ($row = mysqli_stmt_fetch($stmt))

編輯:

 mysqli_stmt_bind_result($stmt, $keyframeurl, $videoid, $title, $year, $sound, 
     $color, $duration, $genre); 
     //store result so num rows can be counted 
     $result = mysqli_stmt_store_result($stmt); 
     //fetch results 
     while (mysqli_stmt_fetch($stmt)) { 
      echo "<tr>"; 
       echo "<td><a href=\"".$keyframeurl."\">".$videoid."</a></td>"; 
       echo "<td>" . $title . "</td>"; 
       echo "<td>" . $year . "</td>"; 
       echo "<td>" . $sound . "</td>"; 
       echo "<td>" . $color . "</td>"; 
       echo "<td>" . $duration . "</td>"; 
       echo "<td>" . $genre. "</td>"; 
     echo "</tr>"; 
     } 
+0

['mysqli_stmt_fetch'](http://www.php.net/manual/en/mysqli-stmt.fetch.php)沒有回報值基於綁定參數。請閱讀鏈接。 – Jon 2013-04-06 04:06:49

+0

@Jon我編輯了我的回答 – Amir 2013-04-06 04:11:39

0

@您的常識 - 您看到allenbell_nc沒有必要「......只是擺脫所有那些混亂和使用PDO」就像您推斷的那樣。僅僅因爲你對mysqli擴展的錯誤印象和預先準備好的陳述並不意味着其他人應該盡最大努力去做,而不是進行深入而痛苦的研究。畢竟,這是什麼stackoverflow是關於,不是嗎?深入研究的答案。

@allenbell_nc - 要回答你的問題,我不認爲你的問題與你使用通配符和東西有關。問題在於您嘗試使用 mysqli_fetch_array()的代碼行。這很可能會引發抱怨參數1($ result)的錯誤,因爲mysqli_stmt_store_result()用於您希望稍後查找查詢返回的行數的情況,因此它會返回布爾值(true或false),而不是結果集。

相反,使用mysqli_stmt_bind_result()在執行調用後,然後調用在while條件mysqli_stmt_fetch(),終於在同時身體條件,這將有助於您存儲和隨後使用array_push()前回聲出關聯數組的內容。

一個簡單的例子(由卡森麥當勞@先生提供思想[http://www.ioncannon.net/programming/889/php-mysqli-and-multiple-prepared-statements/][1]) :

...
$評論=陣列();

$comment_stmt->bind_param('i', $post_id); 
    if ($comment_stmt->execute()) 
    { 
    $comment_stmt->bind_result($user_id); 
    while ($comment_stmt->fetch()) 
    { 
     array_push($comments, array('user_id' => $user_id)); 
     //Now you can go ahead and make use of $comments however you want, whether as stored in an $_SESSION array variable or just to echo it out! As Demonstrated Below: 

     $_SESSION = $comments; 
     echo $_SESSION['user_id']; 
    } 
    } 

...

希望幫助古德勒克給你 - 第一次提問者,因爲這也是我第一次的答案 - 你的項目。

+0

這只是無法使用的方法。它僅適用於愚蠢的例子,但對於真實應用程序無法使用。如果你不需要單個$ user_id而是一行10列?如果你正在創建一個抽象方法並且**不知道返回的值是什麼?** – 2013-04-15 09:23:37

+0

與將任意數量的變量綁定到查詢中的情況相同。 mysqli不是「錯誤的」。它只是無法使用 – 2013-04-15 09:35:11

+0

@ user1676047 - 感謝您的建議!我會試一試。 – 2013-04-16 00:08:50