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

时间:2011-07-14 03:02:02

标签: php mysqli prepared-statement

我一直在用这个疯狂的问题结束我的想法。

使用mysqli我运行以下查询

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

它应该像这样返回数组中的每一行:

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
        )

)

相反,我得到同一行的四个副本,如下所示:

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
        )

)

问题在于我想到的这段代码:

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

如果我像这样放print_r($fields)

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

正确打印结果的每一行。但如果我把print_r($results)放在这里:

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

...然后我得到一个包含重复只有一行的大型数组。在我看来,$ results数组没有正确填充。好像数据来自数据库。

任何帮助都会很棒,我真正想到了这个问题!

修改

以上是在上面发布的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));

2 个答案:

答案 0 :(得分:0)

您很可能已将$fields声明为代码中的某个位置(显式或隐式)。你附加到$results的每个数组元素实际上都是同一个引用的副本,因此每个数组元素都指向php中相同的内存位,这恰好是从查询中获取的最后一行

我建议你在进行变量绑定/结果提取之前先做一个unset($fields),这会破坏$fields变量的参考设置。

答案 1 :(得分:0)

好的,我已经找到了解决方案。虽然不是很优雅,但它的工作原理:)。我只是创建一个名为$fieldNames的数组,并存储通过mysql返回的字段的名称。然后在fetch() while循环中,我只是循环遍历$fieldNames并从$results设置$fields[$fieldNames]。通过解释,下面的代码可能比我能做的更有意义!

$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++;
}