1

As I was looking for an answer to another question, I came across this thread:

bind_result into an array PHP mysqli prepared statement

It answers the very same question. I don't know how to delete my own post, which now I see as a duplicate of previously asked question. Moderator, please feel free to delete this post. Thanks.


I'm converting my php scripts to prepared statements, but I'm having trouble sorting out the right syntax for fetching associative array. The previously built non-prepared version works, but I can't figure out how to retrieve mysqli_result. I have tried various mutation of what I thought might work (some of which noted below), but none worked so far. I either get "object given" or "boolean given". What am I doing wrong? How can I retrieve mysqli_result?

Here is the non-prepared version of the php script that works (simplified to demonstrate the difference between working version vs. non-working prepared-statment version):

// THIS WORKS
$dbh = mysqli_connect('localhost', $db_user, $db_password);
mysqli_select_db($dbh, $db_dbname);

$num = 123456; 
$num0 = 0; 
$num1 = 1; 
$i = 0; 
$myList = array(array()); 

$query = "SELECT col1, col2, col3, col4, col5, colB, colC 
    FROM tableOne LEFT OUTER JOIN tableTwo ON( tableOne.col3=tableTwo.colA )
    WHERE col6='" . $num . "' AND col7='" . $num1 . "'
    AND col8='" . $num1 . "' AND col9='" . $num0 . "'";

$data = mysqli_query($dbh, $query);

if ($data) { $dataCount = mysqli_num_rows($data); }

if ($dataCount > 0) {
    while( $row = mysqli_fetch_assoc($data) ) {
        $thisCol1 = $row['col1']; 
        $thisCol2 = $row['col2'];
        $thisCol3 = $row['col3']; 
        $thisCol4 = $row['col4'];
        $thisCol5 = $row['col5'];
        if ($thisCol1 > $thisCol2) {
            $myList[$i]["result1"] = "good"; 
        } else { 
            $myList[$i]["result1"] = "bad";
        }
        if ($thisCol3 > $thisCol4) { 
            $myList[$i]["result2"] = "good"; 
        } else { 
            $myList[$i]["result2"] = "bad"; 
        }
        $myList[$i]["thisCol5"] = $row['col5'];
        $myList[$i]["thisColB"] = $row['colB'];
        $myList[$i]["thisColC"] = $row['colC'];
        $i = $i + 1;
    }
    echo json_encode($myList);
} else {
    echo "no entry found";
}

Here's the attempt at converting to prepared statement that gives me error:

// THIS GIVES ME ERROR
$mysqli = new mysqli('localhost', $db_user, $db_password, $db_dbname);
$stmt = $mysqli->stmt_init();

$num = 123456; 
$num0 = 0; 
$num1 = 1; 
$i = 0; 
$myList = array(array()); 

$query = "SELECT col1, col2, col3, col4, col5, colB, colC 
    FROM tableOne LEFT OUTER JOIN tableTwo ON( tableOne.col3=tableTwo.colA )
    WHERE col6=? AND col7=? AND col8=? AND col9=?";

if($stmt->prepare($query)){

    $stmt->bind_param("iiii", $num, $num1, $num1, $num0);

    $stmt->execute() or trigger_error($mysqli->error);

    if ($stmt->store_result()) {

        $stmt->bind_result($col1,$col2,$col3,$col4,$col5,$colB,$colC);

        while mysqli_fetch_assoc($stmt) {
            $thisCol1 = $col1;  
            $thisCol2 = $col2;
            $thisCol3 = $col3;  
            $thisCol4 = $col4; 
            $thisCol5 = $col5;
            if ($thisCol1 > $thisCol2) { 
                $myList[$i]["result1"] = "good"; 
            } else { 
                $myList[$i]["result1"] = "bad";
            }
            if ($thisCol3 > $thisCol4) { 
                $myList[$i]["result2"] = "good"; 
            } else { 
                $myList[$i]["result2"] = "bad"; 
            }
            $myList[$i]["thisCol5"] = $col5;
            $myList[$i]["thisColB"] = $colB;
            $myList[$i]["thisColC"] = $colC;
            $i = $i + 1;
        }
        echo json_encode($myList);
    }
} else {
    echo $mysqli->error;
    echo "no entry found";
    $mysqli->close();  // close connection
}

I tried $rows=$stmt->execute() and mysqli_fetch_assoc($rows), which didn't work. I also tried $rows=$stmt->bind_result($col1,$col2,$col3,$col4,$col5,$colB,$colC), but it didn't work either. I then tried $rows=$stmt->fetch(), again no good.

I can't find the proper syntax for retrieving mysqli_result from the executed statement. I'd so appreciate any and all help.

RESOLVED: Thanks to PeeHaa, I learned how to do this using prepared statement. Here's the first step towards getting $myList to return the array I'm looking for.

// REPLACE THE if($stmt->prepare($query)){} SEGMENT WITH THE FOLLOWING 
// AND THE SOLUTION WILL BE STARING AT YOU:

if($stmt->prepare($query)){
    $stmt->bind_param("iiii", $num, $num1, $num1, $num0);
    $stmt->execute() or trigger_error($mysqli->error);
    $rows = $stmt->get_result();
    while ($row=mysqli_fetch_array($rows)){
        echo "<p>" . $row['col1'] . "</p>";
    }
}
Community
  • 1
  • 1
Naomi
  • 77
  • 1
  • 4
  • 11
  • 3
    You need to: 1) read the error; 2) Read the manual for the entry "mysqli_fetch_assoc"; 3) check what you wrote instead; The answer shall be revealed. – Damien Pirsy Feb 20 '13 at 19:10
  • You know, I read the manual entry for "mysqli_fetch_assoc", but unfortunately, I don't get it. The examples posted there also does not help me see how I may apply it to prepared statement. I might be wrong, I don't see many examples showing the use of essential functions with prepared statements on php.net pages. Do you have suggestion for a specific reference I should look at? I'd appreciate that very much. – Naomi Feb 20 '13 at 19:19
  • @PeeHaa, I added more line breaks. Is it readable, or do you think I need a lot more line breaks? – Naomi Feb 20 '13 at 19:24
  • Well if it would have been my code I would drop all those single line `if` / `else` statements. As well as those multiple assignment things on a single line `$thisCol1 = $col1; $thisCol2 = $col2;`. That is just waiting for bad things to happen. If not now it will be somewhere next month when you have to debug it. Just my 2c, but I'm sure the future you will thank you :) – PeeHaa Feb 20 '13 at 19:26
  • @PeeHaa, in my real code, I don't have multiple assignment things on a single line. I use line break after every single ; in my php files. However, I thought it might be much more readable this way on Stackoverflow. It sounds like I was mistaken. I'll update it now. Thank you for letting me know. – Naomi Feb 20 '13 at 19:30
  • @DamienPirsy, I'd so appreciate it if you can point to some reference page that includes sample code that uses mysqli_fetch_assoc function in mysqli prepared statements. I did scour the web, looking for it, but none of them mapped it out properly for me... – Naomi Feb 20 '13 at 19:37
  • @PeeHaa, yes, I have called the get_result function before the while statement (see above.) I use $result variable in the code for other purpose, so I used $rows instead. I did read about PDO, but then that's another new thing I need to figure out -- and I'm not entirely sure if it has more samples and tutorials than regular prepared statements. – Naomi Feb 20 '13 at 19:48
  • 1
    For PDO I know a pretty good tutorial: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers – PeeHaa Feb 20 '13 at 19:49

1 Answers1

0

According to http://www.php.net/manual/en/mysqli-result.fetch-assoc.php fetch_assoc() accepts either void parameter or mysqli_result. But you are sending in mysqli_statement at:

while mysqli_fetch_assoc($stmt) {

EDIT: i see you are binding results to variables. If you want the variables to be filled, use this cycle instead:

while ($stmt->fetch()) {

(http://www.php.net/manual/en/mysqli-stmt.fetch.php)

Kyborek
  • 1,519
  • 11
  • 20
  • Thank you for the suggestion. It looks like I can get what I need with the solution that came to me from PeeHaa (and it's posted above.) That said, I'd definitely look into your suggestion, because it always helps to know different ways to arrive at the same thing. I really appreciate it. – Naomi Feb 20 '13 at 20:21
  • You know, I tried it and it gave me Fatal error: Method name must be a string. – Naomi Feb 20 '13 at 20:25
  • Did you copy my code, or write it by yourself? http://php.syntaxerrors.info/index.php?title=Function_name_must_be_a_string – Kyborek Feb 21 '13 at 07:55
  • I believe I copied your code, replacing the while statement in the "THIS GIVES ME ERROR" version of the code. – Naomi Feb 21 '13 at 18:36