为啥我需要在 foreach 循环后取消设置 $value

Posted

技术标签:

【中文标题】为啥我需要在 foreach 循环后取消设置 $value【英文标题】:Why do I need unset $value after foreach loop为什么我需要在 foreach 循环后取消设置 $value 【发布时间】:2018-04-18 02:12:40 【问题描述】:

我正在使用 php 中的数组,我对 unset() 函数感到困惑,这是代码:

<?php

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

unset($value);
print_r($array);

?>

是否有必要 unset($value),当 $value 在 foreach 循环后仍然存在时,这是一种好习惯吗?

【问题讨论】:

@nogad - 不正确,它存在于定义它的函数范围内 从 PHP 参考书 - 初级到中级书 猜我从来没有检查过,因为我从来不想使用它,必须是循环中的最后一个值。所以在这种情况下“4”你可以从内存中删除它,但可能不是什么大问题 @kronberger - 你没有,虽然如果你“通过引用”定义它(例如foreach ($array as &amp;$value) 它可能会给粗心的人带来意想不到的问题,尤其是当你第二次遍历该数组时 顺便说一句:$value + 10; ?什么都不做 【参考方案1】:

没有必要在您使用它的当前上下文中使用unsetunset 只会破坏变量及其内容。

在您给出的示例中,这是循环创建$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,这不会搞砸吗? 只有当 $value 被引用使用时才会搞砸,像这样:foreach ($array as &amp;$value) $value + 10; 【参考方案2】:
<?php
    $array = array(1, 2, 3, 4);
    foreach ($array as &$value) 
        $value = $value + 10;
    
    unset($value);
    print_r($array);

你可能会泄露 "&amp;"

【讨论】:

【参考方案3】:

我知道这篇文章很旧,但我认为这个信息非常重要: 你问:

是否需要取消设置($value),当 $value 在 foreach 之后仍然存在时 循环,这是一种好习惯吗?

这取决于您是按值还是按引用进行迭代。

第一种情况(按值):

$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

未设置的相同代码:

$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]

我希望这对将来的某人有用。 :)

【讨论】:

这应该是公认的答案。如果他们不了解价值/参考的东西,没有经验的开发人员可能会搞砸。 Sitenote:(没有经验的)开发人员应该使用 PHP Inspections EA(或任何其他静态代码分析器?),他们会收到有关该可能问题的通知。如果多个开发人员在一个项目上工作,迟早有人会忘记这个未设置的小东西(或其他东西),然后让 IDE 监视它是件好事。 这个答案绝对应该被接受 - 作为一个答案,它解释了 unset() 在不同 foreaches 之后的整个方面

以上是关于为啥我需要在 foreach 循环后取消设置 $value的主要内容,如果未能解决你的问题,请参考以下文章

PHP - 在foreach循环中取消设置数组元素[重复]

idea中foreach为啥分两行

为啥我不能在 foreach 循环中设置迭代变量的属性?

为啥覆盖 Parallel.foreach 循环的 .NET 单元测试依赖于硬件?

如何在 SwiftUI 的 foreach 循环中设置切换状态

为啥这个 foreach 循环缺少类中的属性?