【问题标题】:mysqli_fetch_array(), prepared statement, and LIKE statementmysqli_fetch_array()、prepared statement 和 LIKE 语句
【发布时间】:2013-03-28 14:46:21
【问题描述】:

我正在尝试将 mysqli 准备好的语句与 LIKE 语句查询和通配符运算符一起使用。在调试完代码中的 echo 语句后,我可以看到我的 while 语句没有执行。你能看出我在这里做错了什么吗?

这是我第一次在这个论坛上提问,如果这不是一个好问题,我深表歉意;我花了 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);
    }

感谢您的建议!

【问题讨论】:

  • 我之前用过 MySQLi,但是把它变成数组是一个很大的挑战。如果您刚刚开始该程序,我建议您学习 PDO,因为它使数组和检索信息比 MySQLi 容易得多。 MySQLi_STMT 只是.... 不完整感觉就像是中途放弃了。
  • “我可以看到我的 while 语句没有执行”——任何错误信息?
  • 是的,这不是一个好问题。只是观看代码不是要走的路。代码必须 run 代替。你应该分开你的目标,而不是一次做所有的事情。首先使用准备好的语句对事物进行排序,然后进行 LIKE 或其他任何特定查询。是的 - 如果你不想浪费你的时间,move to PDO 直到为时不晚
  • 您正在绑定结果集,因此您可以将while 循环设置为使用mysqli_stmt_fetch($stmt),然后使用您为结果绑定的变量。不过,正如其他人所说,现在出去使用 PDO ^^

标签: php mysqli prepared-statement


【解决方案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 调用负载进行比较

【讨论】:

  • get_result 在喜欢工作的地方很挑剔。与此处的其他人相比,感谢您提供了一个非常好的答案。
【解决方案2】:

@Your Common Sense - 你看,allenbell_nc 没有必要像你推断的那样“......只是摆脱所有这些混乱并使用 PDO”。仅仅因为您对带有准备好的语句的 mysqli 扩展有一个错误的印象,并不意味着其他人应该在稍有麻烦的情况下就取消它,而不是进行深入但痛苦的研究。毕竟,这就是 stackoverflow 的意义所在,不是吗?经过充分研究的答案..

@allenbell_nc - 要回答您的问题,我认为您的问题与您使用通配符之类的东西无关。问题在于您尝试使用的代码行 mysqli_fetch_array()。这很可能会引发一个抱怨参数 1 ($result) 的错误,因为 mysqli_stmt_store_result() 用于您以后想要查找从查询返回的行数的情况,因此它返回布尔值(true 或 false)和不是结果集。

INSTEAD,在执行调用之后使用mysqli_stmt_bind_result(),然后在while 条件中调用mysqli_stmt_fetch(),最后在while 条件主体中使用array_push(),这将帮助您存储并随后回显您的关联数组的内容.

快速示例(由 Carson McDonald 先生提供的想法 @ [http://www.ioncannon.net/programming/889/php-mysqli-and-multiple-prepared-statements/] [1]):

...
$cmets = 数组();

  $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'];
    }
  }

...

希望对您有所帮助,祝您好运 - 第一次提问,因为这也是我第一次回答您的项目。

【讨论】:

  • 这只是不可用的方法。它仅适用于愚蠢的示例,但不适用于现实生活中的应用程序。如果您不需要单个 $user_id 而是一行 10 列怎么办?如果您正在创建一个抽象方法并且根本不知道返回了哪些值?
  • 将任意数量的变量绑定到查询中也是如此。 mysqli 不是“错误的”。它只是无法使用
  • @user1676047 - 感谢您的建议!我会试一试的。
【解决方案3】:
            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>";   
        }

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 2012-08-18
  • 1970-01-01
  • 1970-01-01
  • 2021-07-02
相关资源
最近更新 更多