在PHP foreach中重用collection var作为迭代var

时间:2013-04-30 14:30:56

标签: php foreach

我有一个同事,我注意到他正在以下列方式使用他的foreach:

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

我已经测试了上面的代码,它让我感到惊讶。 PHP大师是否愿意跳进去告诉我为什么这是错的?感觉非常错误。

5 个答案:

答案 0 :(得分: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指出的那样,它迭代了$var而不是$var本身的副本。因此,每次迭代$var的值都在变化,但它不会破坏循环,因为它循环遍历创建的副本。

答案 1 :(得分:0)

即使感觉不对,它仍然有效,因为foreach启动的那一刻,PHP内部已经可以访问数据。

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

您发现的具体问题以及您所说的错误也称为变量重用,您应该阻止它,因为这是code-smell

这不仅感觉不对,编写此类代码也是错误的。告诉你的同事你可以一起编写更好的代码。

答案 2 :(得分: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 
 */
}

答案 3 :(得分:0)

检查此表达式:

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

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

一旦循环完成,$x(数组)内部的foreach会丢失范围而不再存在,剩下的是$x variable,它现在包含最后一个元素原$x array。在这种情况下,这将是3

答案 4 :(得分:0)

你的同事似乎不再需要$var作为循环后的数组了。当PHP初始化foreach循环(仅执行一次)时,它使用来自$var的原始值,因为它现在是一个数组。然后在循环的每一步中,元素的当前元素被分配给名为var new 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);