1

I have a coworker that I noticed was using his foreachs in the following fashion:

foreach ($var as $var) {
    // do stuff here
}

I have tested the code above and it works correctly to my surprise. Would the PHP gurus like to hop in and tell me why this is wrong? It feels very wrong.

4

5 回答 5

4

因为它改变了 的值$var。之后foreach()它不再是一个数组,而是设置为数组中的最后一个值。

$var = array('apple', 'orange');
foreach ($var as $var) {
    echo $var."<br/>";
}
echo $var; //orange

如果您不想更改变量的值,则需要使用不同的变量名称:

$var = array('apple', 'orange');
foreach ($var as $fruit) {
    echo $fruit."<br/>";
}
echo $var; //array

正如@UselessIntern 指出的那样,如果您在循环之后不使用该变量,那很好,但绝对不鼓励这样做,因为它会导致混乱。

正如@PLB 指出的那样,它迭代了$varnot$var本身的副本。所以每次迭代的值都$var在改变,但它不会破坏循环,因为它会循环创建的副本。

于 2013-04-30T14:33:05.617 回答
0

即使感觉不对,它仍然有效,因为从开始的那一刻起foreach,PHP 内部就已经可以访问数据了。

所以即使$var被覆盖,在内存中这个数据仍然存在(原始数组)并且$var在每次迭代中设置为它的当前值。

您发现的具体问题以及您所说的错误也称为变量重用,您应该防止它,因为这是代码异味

不仅感觉不对,写这样的代码也是不对的。告诉你的同事,这样你们就可以一起编写更好的代码。

于 2013-04-30T14:33:37.380 回答
0

因为它是一个循环。表演:

array > string
array > string

所以

foreach ($var AS $var){
 /*
 Is basically being re-read at the end so your foreach can read the array again to get  the next step of the array 

 array > string 
 recheck array > string
 recheckarray > string 
 */
}
于 2013-04-30T14:34:19.777 回答
0

检查这个表达式:

$x = array(1,2,3);
foreach ($x as $x) {
    echo $x; //prints 123
}

这里发生的是foreach提取数组的第一个元素$x并覆盖到$x自身中。$x然而,位于关键字左侧的数组变量as仍保留在参数的内部范围内,foreach这就是循环正常工作的原因。

一旦循环完成, (数组)$x内部的 whichforeach就会失去作用域并且不再存在,剩下的就是$x variable现在包含原始$x array. 在这种情况下,将是3

于 2013-04-30T14:36:37.033 回答
0

您的同事似乎不再需要$var循环后的数组。当 PHP 初始化 foreach 循环(只执行一次)时,它使用原始值,$var因为它现在是一个数组。然后在循环中的每一步,元素的当前元素都被分配给一个名为 的var var。请注意,原始数组$var不再存在。循环$var后将具有原始数组中最后一个元素的值。

检查这个小例子,它演示了我所说的:

$a = array(1,2,3);
foreach($a as $a) {
    echo var_dump($a);
}

// after loop
var_dump($a); // integer(3) not array

我可以想象你的同事这样做是为了节省一点内存,因为对数组的引用将被覆盖,因此垃圾收集器将在下次运行时删除它的内存,但我不建议你这样做,因为它的可读性较差.

只需执行以下操作,它是相同的,但更具可读性:

$array = array(1,2,3);
foreach($array as $value) {
    echo var_dump($value);
}

delete($array);
delete($value);
于 2013-04-30T14:39:44.897 回答