2013-04-06 236 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