【问题标题】:php counter is being reset each loop每个循环都会重置 php 计数器
【发布时间】:2011-11-26 06:19:56
【问题描述】:

我有一组相当复杂的循环,它们从 mysql 中提取数据并将其与数组中的值进行比较并增加一个计数器。当我在计数器增加时回显一个标志时,我得到一个 bijilion 标志(从 mysql 查询返回的记录大约为 2600 条)。但是每次打印时,计数器始终为 1,当我最后打印计数器的值时,它显示为零。好像有什么东西正在重新设置计数器……

代码

# ARRAY
$demographics=array(
    "region"=>array(
        "Northeast"=>array('total'=>0,'consented'=>0,'completed'=>0),
         //more...
        "West"=>array('total'=>0,'consented'=>0,'completed'=>0)
    ),"societal envirn"=>array(
        "Urban"=>array('total'=>0,'consented'=>0,'completed'=>0)
    ),"age"=>array(
        '18-19'=>array('total'=>0,'consented'=>0,'completed'=>0),
        '20-24'=>array('total'=>0,'consented'=>0,'completed'=>0),
         //more...
        '55-59'=>array('total'=>0,'consented'=>0,'completed'=>0)
    ),
    //more...
);

# LOOPS
while ($dbrecord = mysql_fetch_assoc($surveydata)) {
    foreach ( $dbrecord as $dbfield=>$dbcellval ) {
        foreach ( $demographics as $demographic=>$options ) {
            foreach ( $options as $option=>&$counter ) {
                if($demographic==="age"){
                    list($min,$max) = explode('-', $option);
                    if ($dbcellval >= $min && $dbcellval <= $max){
                        $counter['total']++;
                        echo '$' . $option . "['total'] = " . $counter['total'] . "<br />";
                        if ($dbrecord['consent']==="1"){
                            $counter['consented']++;
                            echo '$' . $option . "['consented'] = " . $counter['consented'] . "<br />";
                            if ($dbrecord['completion status']==="complete") {
                                $counter['completed']++;
                                echo '$' . $option . "['completed'] = " . $counter['completed'] . "<br />";
                                break 3;
                            } // if
                        } // if
                        break 2;
                    }
                } // if age
                else if ($option===$dbcellval){
                    $counter['total']++;
                    echo '$' . $option . "['total'] = " . $counter['total'] . "<br />";
                    if ($dbrecord['consent']==="1"){
                        $counter['consented']++;
                        echo '$' . $option . "['consented'] = " . $counter['consented'] . "<br />";
                        if ($dbrecord['completion status']==="complete") {
                            $counter['completed']++;
                            echo '$' . $option . "['completed'] = " . $counter['completed'] . "<br />";
                            break 3;
                        } // if
                    } // if
                    break 2;
                } // else if $option==$dbcellval
            } // foreach $options
        } // foreach $demographics
    } // foreach $dbrecord
} // while

样本输出

$40-44['total'] = 1
$White['total'] = 1
$35-39['total'] = 1
$Northeast['total'] = 1     // the 'total' counter is 1
$Northeast['consented'] = 1
$Northeast['completed'] = 1
$South['total'] = 1
$Northeast['total'] = 1     // notice the 'total' counter is 1 again :(
$Northeast['consented'] = 1
$Northeast['completed'] = 1

【问题讨论】:

  • 是否在循环外使用或声明了计数器?如果没有,它的范围将被限制在第一次使用的循环中,并在每次循环循环时重置。
  • 嗨,Kevin,我很确定 php 的作用域不是那样的。

标签: php loops foreach while-loop counter


【解决方案1】:

您从 foreach 指令定义计数器,如 foreach($foo as $key=&gt;$value) 中的 $value,当使用 foreach 时,您只有 $counter 的本地副本。

您需要使用foreach($foo as $key=&gt;&amp;$value) 或从$demographics 引用计数器的完整数组路径。

【讨论】:

  • 嗨 regilero,我尝试添加 &amp;,但似乎没有帮助(我更新了上面的代码以反映我对 &amp; 所做的事情)。我认为我不能在 $demographics 中引用计数器的完整路径,因为这就是我循环的原因。
  • 啊,在@dar7yl 的回答之后,我明白你的意思了。谢谢!
【解决方案2】:

您需要在每个级别引用您的数组,否则您正在处理数据的副本:

foreach ( $dbrecord as $dbfield=>$dbcellval ) {
    foreach ( $demographics as $demographic => &$options ) {
        foreach ( $options as $option => &$counter ) {
            if($demographic==="age"){
                list($min,$max) = explode('-', $option);
                if ($dbcellval >= $min && $dbcellval <= $max){
                    $counter['total']++;

【讨论】:

    【解决方案3】:

    如果您只是坚持使用 $demographics 变量会怎样。

    ...
    foreach ( $options as $option ) {
       ...
       $demographics[$option]['total']++;
    
    ...
    

    【讨论】:

    • 嗨 Ayman,谢谢,但我已经这样做了(请参阅我之前发布的代码)。每个选项(北、南)都需要有自己的一组计数器
    • 如果我的理论是正确的,那么您的问题与范围有关。您是在循环开始后第一次创建“$counter”变量。换句话说,您在循环的每次迭代中重新创建“$counter”变量。
    • @Ayman:php 的变量范围不适用于循环。在循环中第一次使用的变量不会在每次迭代中重置
    • 哦,不错,但$counter 不是真的。由于 foreach 循环,$counter 解析为“region”、“age”等,所以它实际上是 age['total']。不过以防万一,我试过了,还是不行。
    • @AymanSafadi,实际上这种做法:计数不会停留在 1,但现在我认为它只是一组计数器,而不是 38 组。
    猜你喜欢
    • 2020-03-24
    • 2021-08-26
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多