mysqli_fetch_array(), prepared statement, and LIKE statement

家住魔仙堡 提交于 2019-12-25 02:56:02

问题


I'm trying to use mysqli prepared statements with a LIKE statement query and wildcard operators. After debugging be sprinkling echo statements throughout the code, I can see that my while statement is not executing. Can you see what I'm doing wrong here?

This is my first time asking on this forum, so I apologize if this isn't a good question; I've spent 6 hours trying to get the prepared statement section of my code to work and I can't find any threads addressing my question that don't go completely over my head (e.g. How can I put the results of a MySQLi prepared statement into an associative array?). The two closest I found were:

Using wildcards in prepared statement - MySQLi and Combine PHP prepared statments with LIKE.

Here's the relevant excerpt of my code:

    //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);
    }

Thanks for any advice!


回答1:


You are mixing 2 styles of fetching results. Either use ugly bind_result way (and get your data using fetch() then), or try to use get_result() - so, you'll be able to use fetch_array() (not guaranteed though).

Anyway, just get rid of all that mess and use 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

I hope you properly sanitized your $order variable. The best way would be apparently to add it via placeholder, so, you will need a library that allows it, SafeMysql for example:

$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

Note the amount of code and compare with that load of raw API calls you are using at the moment




回答2:


@Your Common Sense - You see there is no need for allenbell_nc to "... just get rid of all that mess and use PDO" like you inferred. Just because you've got an erroneous impression of the mysqli extension with prepared statements does not mean that others should do away with it at the slightest hint of trouble as opposed to carrying out indepth but painful research. After all, this is what stackoverflow is about, isn't it? well researched answers..

@allenbell_nc - To answer your question, I do not think your problem has to do with your use of Wild cards and stuff. The problem lies in your line of code where you attempt to make use of mysqli_fetch_array(). This will very likely throw an error complaining about parameter 1 ($result), because mysqli_stmt_store_result() is used in cases where you want to later find the number of rows returned from a query, so it therefore returns boolean(true or false) and NOT a result set.

INSTEAD, use mysqli_stmt_bind_result() after the execute call then call mysqli_stmt_fetch()in the while condition, before finally using array_push() in the while condition body which will help you to store and subsequently echo out the contents of your ASSOCIATIVE array.

A QUICK EXAMPLE(Idea provided by Mr. Carson McDonald @ [http://www.ioncannon.net/programming/889/php-mysqli-and-multiple-prepared-statements/][1]):

...
$comments = array();

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

...

Hope that helps, goodluck to you - a first time asker, as this is also my first time answer - on your project.




回答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))

Or while ($row = mysqli_stmt_fetch($stmt))

Edit:

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


来源:https://stackoverflow.com/questions/15846583/mysqli-fetch-array-prepared-statement-and-like-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!