开发者

How to get Mysqli Stmt to fetch multiple rows correctly?

I've been reaching the end of my ideas with this crazy problem.

Using mysqli I run the following query

SELECT * FROM `shop_cart` WHERE `tmpID`=?

It should return each row in an array like this:

Array
(
    [0] => Array
        (
            [id] => 1
            [tmpID] => af83abab7fdee8eb0cf8919f171cdeec
            [pID] => 800
            [qty] => 2
            [time] => 1310076898
        )

    [1] => Array
        (
            [id] => 2
            [tmpID] => af83abab7fdee8eb0cf8919f171cdeec
            [pID] => 797
            [qty] => 1
            [time] => 1310076903
        )

    [2] => Array
        (
            [id] => 3
            [tmpID] => af83abab7fdee8eb0cf8919f171cdeec
            [pID] => 883
            [qty] => 1
            [time] => 1310076907
        )

    [3] => Array
        (
            [id] => 4
            [tmpID] => af83abab7fdee8eb0cf8919f171cdeec
            [pID] => 795
            [qty] => 1
            [time] => 1310076909
        )

)

Instead I get four copies of the same row like this:

Array
(
    [0] => Array
        (
            [id] => 4
            [tmpID] => af83abab7fdee8eb0cf8919f171cdeec
            [pID] => 795
            [qty] => 1
            [time] => 1310076909
        )

    [1] => Array
        (
            [id] => 4
            [tmpID] => af83abab7fdee8eb0cf8919f171cdeec
            [pID] => 795
            [qty] => 1
            [time] => 1310076909
        )

    [2] => Array
        (
            [id] => 4
            [tmpID] => af83abab7fdee8eb0cf8919f171cdeec
            [pID] => 795
            [qty] => 1
            [time] => 1310076909
        )

    [3] => Array
        (
            [id] => 4
            [tmpID] => af83abab7fdee8eb0cf8919f171cdeec
            [pID] => 795
            [qty] => 1
            [time] => 1310076909
        )

)

The problem lies somewhere in this bit of code I think:

while ($query->fetch()){ 
    $results[] = $fields;
}

If I put print_r($fields) in like this:

while ($query->fetch()){ 
    print_r($fields);
    $results[] = $fields;
}

It prints each row of the results correctly. But if I put print_r($results) in here like this:

while ($query->fetch()){ 
    $results[] = $fields;
}
print_r($results);

...then I get one large array containing duplicate copes of only one row. It seems to me that the $results array isn't getting populated correctly. It seems that the data is coming out of the database okay.

Any help would be great, I'm really at the end of my rope at figuring this out!

Edit

Here's some more code preceding (and including) the fetch() loop as posted above.

// Generate Types
$types = '';                        //initial sting with types
foreach($params as $param) {        //for each element, determine type and add
    if(is_int($param)) {
        $types .= 'i';              //integer
    } elseif (is_float($param)) {
        $types .= 'd';              //double
    } elseif (is_string($param)) {
        开发者_JAVA百科$types .= 's';              //string
    } else {
        $types .= 'b';              //blob and unknown
    }
}
array_unshift($params, $types);

$query = $this->connection->stmt_init();
if($query->prepare($sql)) {
    call_user_func_array(array($query,'bind_param'),$this->refValues($params));
    $query->execute(); 

    if($fetch){ // Only if we want to return an array of results
        // Get Metadata
        $meta = $query->result_metadata();

        $fields = $results = array();
        while ($field = $meta->fetch_field()) { 
            $var = $field->name; 
            $$var = null; 
            $fields[$var] = &$$var; 
        }

        call_user_func_array(array($query,'bind_result'),$fields);

        while ($query->fetch()){ 
            pr($fields);
            $results[] = $fields;
        }
    }
} else die(printf("Error: %s\n", $this->connection->error.' : '.$this->lastQ));


Most likely you've declared $fields to be a reference somewhere in your code (explicitly or implicitly). Each array element you append to $results is actually going to be a copy of that same reference, so each array element points to the same bit of memory in php, which'll happen to be the last row fetched from your query.

I'd suggest doing an unset($fields) before you do your variable binding/result fetching, which would break the reference setting on the $fields variable.


Okay, I've worked out a solution. Albeit not a very elegant one, but it works :). I'm just making an array called $fieldNames and storing the names of the fields being returned via mysql. Then in the fetch() while loop I'm just looping through the $fieldNames and setting $results from $fields[$fieldNames]. The code below might make more sense than I can make by explaining it!

$fields = $results = array();
while ($field = $meta->fetch_field()) { 
    $var = $field->name; 
    $fields[$var] = &$$var; 
    $fieldNames[] = $var;
}

$fieldCount = count($fieldNames);

call_user_func_array(array($query,'bind_result'),$fields);

$i=0;
while ($query->fetch()){
    $key = $arKey ? $fields[$arKey] : $i;
    for($l=0;$l<$fieldCount;$l++) $results[$key][$fieldNames[$l]] = $fields[$fieldNames[$l]];
    $i++;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜