简体   繁体   English

如何让 Mysqli Stmt 正确获取多行?

[英]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使用 mysqli 我运行以下查询

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:如果我这样输入print_r($fields)

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:但是如果我把print_r($results)像这样放在这里:

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.在我看来, $results 数组没有正确填充。 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.这是上面发布的 fetch() 循环之前(包括)的更多代码。

// 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)) {
        $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).您很可能已将$fields声明为代码中某处的引用(显式或隐式)。 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.您从 append 到$results的每个数组元素实际上都是同一引用的副本,因此每个数组元素都指向 php 中 memory 的同一位。

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.我建议在您进行变量绑定/结果获取之前执行unset($fields) ,这会破坏$fields变量上的引用设置。

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.我只是创建了一个名为$fieldNames的数组并存储通过 mysql 返回的字段的名称。 Then in the fetch() while loop I'm just looping through the $fieldNames and setting $results from $fields[$fieldNames] .然后在fetch() while 循环中,我只是遍历$fieldNames并从$fields[$fieldNames]设置$results 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++;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM