为什么我需要在 foreach 循环之后取消设置 $value?

8

我在 PHP 中玩弄数组,但是我对 unset() 函数感到困惑,以下是代码:

<?php

$array = array(1, 2, 3, 4);
foreach ($array as $value) {
    $value + 10;
}
unset($value);
print_r($array);

?>

在使用foreach循环后,如果$value的值仍然存在,是否有必要使用unset($value)来释放内存?这样做是否是良好的编程实践?


1
@nogad - 不正确,它存在于定义它的函数的范围内。 - Mark Baker
从PHP参考-初学者到中级书籍 - kronberger
我猜我从未检查过,因为我从未想过要使用它,应该是循环的最后一个值。所以在这种情况下是“4”,你可以将其从内存中删除,但不太可能有什么大问题。 - user6763587
2
顺便说一下:$value + 10;?什么也没做。 - user6763587
感谢回答 :) - kronberger
显示剩余3条评论
4个回答

33

我知道这篇帖子很老,但我认为这个信息非常重要:

当foreach循环结束后$value仍然存在时,是否有必要使用unset($value),这样做好吗?

这取决于你是按还是按引用迭代。

第一种情况(按值迭代):

$array = array(1, 2, 3, 4);
foreach ($array as $value) {

    //here $value is 1, then 2, then 3, then 4

}

//here $value will continue having a value of 4
//but if you change it, nothing happens with your array

$value = 'boom!';
//your array doesn't change.

所以不需要取消设置 $value

第二种情况(引用方式):

$array = array(1, 2, 3, 4);
foreach ($array as &$value) {

    //here $value is not a number, but a REFERENCE.
    //that means, it will NOT be 1, then 2, then 3, then 4
    //$value will be $array[0], then $array[1], etc

}

//here $value it's not 4, it's $array[3], it will remain as a reference
//so, if you change $value, $array[3] will change

$value = 'boom!'; //this will do:  $array[3] = 'boom';
print_r ($array); //Array ( [0] => 1 [1] => 2 [2] => 3 [3] => boom! )

因此,在这种情况下,最好取消 $value 的设置,因为这样做可以打破对数组的引用。这是必要的吗?不是,但如果你不这样做,就应该非常小心。

否则可能会导致意外结果,例如:

$letters = array('a', 'b', 'c', 'd');

foreach ($letters as &$item) {}
foreach ($letters as  $item) {}

print_r ($letters); //output: Array ( [0] => a [1] => b [2] => c [3] => c )
// [a,b,c,c], not [a,b,c,d]

这同样适用于PHP 7.0

使用unset的相同代码:

$letters = array('a', 'b', 'c', 'd');

foreach ($letters as &$item) {}
unset ($item);
foreach ($letters as  $item) {}

print_r ($letters); //output: Array ( [0] => a [1] => b [2] => c [3] => d )
// now it's [a,b,c,d]

我希望这篇文章对未来有所帮助。 :)

7
这应该是被采纳的答案。如果没有理解值/引用的事情,经验不足的开发人员可能会出错。 - nickpapoutsis
1
注:(缺乏经验的)开发人员应使用PHP Inspections EA(或任何其他静态代码分析器?),他们将收到有关可能问题的通知。如果多个开发人员在一个项目上工作,迟早会有人忘记这个小的未设置的事情(或其他事情),然后最好让IDE监视它。 - aProgger
这个答案绝对应该被接受 - 它解释了不同 foreach 后 unset() 整个方面。 - Green Joffer

2

在您当前使用unset的上下文中,没有必要使用它。 unset将简单地销毁变量及其内容。

在您提供的示例中,这是通过循环遍历数组创建$value,然后取消设置该变量。这意味着它在该代码中不再存在。因此,这根本没有任何作用。

为了更直观地说明我的意思,请看这个例子:

$value = 'Hello World';
echo $value;
unset($value);
echo $value;

以下是输出内容:
Hello World<br /><b>NOTICE</b> Undefined variable: value on line number 6<br />

所以你首先会看到Hello World,但是在取消设置该变量后尝试调用它将会导致错误。

回答你的问题,你真的不需要取消设置值;没有必要这样做。因为foreach循环正在设置每个array() + 10$value

取消设置它将导致工作被删除并被遗忘。


如果您不使用 unset($value);,那么如果稍后再使用 $value 进行另一个 foreach,这不会出现问题吗? - WolfieeifloW
2
只有在$value被引用使用时,它才会出错,就像这样: foreach ($array as &$value) { $value + 10; } - Artem Goutsoul

0

我能看到取消设置 $value 的一个原因是确保您不会在同一脚本中无意中再次使用它。我刚刚处理了一个非常令人困惑的错误,这个错误是由于将一个循环内的几行代码复制到另一个循环中而引起的,它使用了第一个循环中 $value 的最终值。至少,如果我对其进行了 unset 操作,由于尝试访问不存在的变量而导致了有用的错误消息。


-1
<?php
    $array = array(1, 2, 3, 4);
    foreach ($array as &$value) {
        $value = $value + 10;
    }
    unset($value);
    print_r($array);

你可能泄漏了"&"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接