PHP:for循环中的静态变量和for循环外的非静态变量之间有什么区别?

时间:2011-02-27 10:39:23

标签: php static scope

例如,

之间有什么区别
$foobar = 0
for ($i=0; $i<20; $i++) {
    //do something using $foobar
    $foobar++;
}

for ($i=0; $i<20; $i++) {
    static $foobar = 0
    //do something using $foobar
    $foobar++;
}

???

上述两个例子的结果与以下不同:

for ($i=0; $i<20; $i++) {
    $foobar = 0
    //do something using $foobar
    $foobar++;
}

所有三种变化都有不同的结果。据我所知,在三个示例的 first 中,$ foobar变量的值越来越大,而在 third 示例中,$ foobar变量的值被重置在每个循环中。我不确定使用静态$ foobar变量的示例是怎么回事。似乎前两个示例在使用$ foobar的for循环部分中应该表现相同,但对我来说情况并非如此。

作为参考,这是我的实际代码(算法尚未完成)。我已经标记了让我思考这个主题的for()循环:

function combine($charArr, $k) {

    $currentsize = sizeof($charArr);
    static $combs = array();
    static $originalsize = "unset";
    if ($originalsize === "unset") $originalsize = $currentsize;
    static $firstcall = true;

    if ($originalsize >= $k) {

        $comb = '';
        if ($firstcall === true) { 
            for ($i = $originalsize-$k; $i < $originalsize; $i++) {
                $comb .= $charArr[$i];
            }
            $combs[] = $comb; 
            $firstcall = false; 
        }
        if ($currentsize > $k) { 

            $comb = ''; //reset
            for ($i=0; $i<$k; $i++) { 
                $comb .= $charArr[$i];
            }
            $combs[] = $comb;

            //########### THE FOR LOOP IN QUESTION ###########              
            for ($i = $k-1; $i >= 0; $i--) { 
            static $range_adj = 0;
                for ( $j = $i+1; $j < $currentsize-$range_adj; $j++ ) { 
                    if ( !($i == 0 and $j == $currentsize-$range_adj-1) ) { 
                        $comb = substr_replace($comb, $charArr[$j], $i, 1); 
                        $combs[] = $comb;
                    }
                }
                $range_adj++;
            }
            if ($currentsize-1 > $k) { 
                array_splice($charArr, 0, 1); 
                combine($charArr, $k); 
            }
        }
        $output = array_values( $combs );
        unset($combs);
        return $output;
    }
    else {
        return false;
    }
}

如果我从for循环中删除$range_adj变量并将其放在所述for循环之前作为非 - static变量,那么我的函数的结果是一样的。这是修改后的for循环的样子:

            $range_adj = 0;
            for ($i = $k-1; $i >= 0; $i--) { 
                for ( $j = $i+1; $j < $currentsize-$range_adj; $j++ ) { 
                    if ( !($i == 0 and $j == $currentsize-$range_adj-1) ) { 
                        $comb = substr_replace($comb, $charArr[$j], $i, 1); 
                        $combs[] = $comb;
                    }
                }
                $range_adj++;
            }

我得到两个不同结果的事实让我相信每种方法都有所不同,因为如果两种方法产生相同的结果,那么我的函数的结果在两种情况下都是相同的,这不是我测试这些场景的情况。为什么我得到两个结果?使用for循环的两种方法测试我的函数,你也会得到不同的结果。

为方便起见,这是原始方法:

            for ($i = $k-1; $i >= 0; $i--) { 
                static $range_adj = 0;
                for ( $j = $i+1; $j < $currentsize-$range_adj; $j++ ) { 
                    if ( !($i == 0 and $j == $currentsize-$range_adj-1) ) { 
                        $comb = substr_replace($comb, $charArr[$j], $i, 1); 
                        $combs[] = $comb;
                    }
                }
                $range_adj++;
            }

???

在我看来,结果应该完全相同,但事实并非如此。如果你运行我的函数,你会发现你对for循环的每个方法都得到了不同的结果。

4 个答案:

答案 0 :(得分:2)

第一个和第二个循环似乎做同样的事情。这是因为,与任何其他静态初始化变量一样,static表示您只初始化一次。当您尝试再次访问它时,它会保留其价值。你会发现静态$foobar仍然存在于你声明/初始化它的循环范围之外;这是由于PHP的本质,与静态变量无关。

只有当您尝试在循环之前访问$foobar时才会明确区别:它不会在第二个代码段中声明,因为您只在循环内创建它,因此您可能会得到一个未定义的 - 变量通知。

答案 1 :(得分:1)

static $foobar = 0;
初始化一次,static $foobar = 0的其他执行没有对$ foobar变量做任何事情

答案 2 :(得分:0)

以上两个编程具有相同的输出,但您的最后编程具有在每个循环期间重置的变量。 当你使用“静态”关键字进行任何变量初始化时,它会保留,直到你不破坏它......或者不破坏你的程序会话。

答案 3 :(得分:0)

您可以以这种方式使用静态来阻止变量在循环内重新初始化

在第一次迭代中,如果静态变量未初始化,那么它将创建它并将其保留在外部上下文中,在每次其他迭代时,PHP将跳过它,因为它已经初始化。

两种结果都是相同的:http://codepad.org/evilks4R

你的函数不同的原因是你的函数是递归的,这意味着函数结合调用自身内部的组合,当在第二次调用combine时取出static关键字时,变量正在重新初始化< / strong>从而使结果不同。

使用static关键字,您可以传递第二个调用的参数,并使用第三个值生成的值。

这是一个将静态成员传递给函数调用的后一个传递的示例:http://codepad.org/gChjx7Om

如果你做了:

$foo_bar = 0;
for(.....)

这将在一个函数内,这样每次调用函数时$foo_bar都会重置为 0 ,因此会覆盖最后的调用计算。

如果您将$foo_bar移到函数外部,然后在您添加的函数中需要的位置:

global $foo_bar

你会得到相同的结果。

http://www.cprogramming.com/tutorial/statickeyword.html