为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

Posted

技术标签:

【中文标题】为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?【英文标题】:Why the temporary variable needs in changing array elements and why it needs to be unset at the end?为什么临时变量需要更改数组元素以及为什么需要在最后取消设置? 【发布时间】:2018-04-23 11:31:28 【问题描述】:

考虑下面的代码 sn-p,它通过引用传递数组的值来直接更改(将值转换为大写)。

<?php
  $colors = array('red', 'blue', 'green', 'yellow');

  foreach ($colors as &$color) 
    $color = strtoupper($color);
  
  unset($color); /* ensure that following writes to
  $color will not modify the last array element */

  print_r($colors);

?>

输出:

Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)

我根本没看懂上面的代码。我对上面的代码没有什么疑问,如下:

    我根本不理解 $color = strtoupper($color); 来自 foreach 循环内部的这个声明。为什么使用了临时变量$color,在函数strtoupper()中为什么没有传递引用&amp;$color而只传递了$color? 为什么变量$color 未设置?在取消设置之前,里面包含什么? 注释的含义是什么“确保以下写入 $color 不会修改最后一个数组元素”,因为数组中的最后一个元素,即 yellow 也被修改了?

简而言之,请逐步向我解释 foreach 循环中的代码中发生了什么。

请有人回答我的疑问。

注意:以上代码示例取自 PHP 手册的数组章节。

【问题讨论】:

删除/注释unset 调用,在末尾添加对$color 变量的写入(当然是在print_r 调用之前),您很快就会得到它。跨度> 重点是在此处注释/删除 unset() 以查看实际发生的魔术。答案即将到来。 附带说明,为了实现这一点,您可以使用 array_map : $colors = array_map("strtoupper", $colors ); 【参考方案1】:

这里是防御性编程。

foreach() 循环的每次迭代中,都会在$color 变量中创建对当前项目值的引用,从而允许向其写入新值。但是,当迭代结束时,$color 变量仍然包含对最后一个数组项的值的引用,允许程序员重用$color 变量来写入更新数组中的该项,这可能不是预期的结果。 unset()ting 循环后的变量会破坏引用并避免这种风险。

建立在您的示例之上:

<?php
$colors = array('red', 'blue', 'green', 'yellow');

foreach ($colors as &$color) 
  $color = strtoupper($color);

//unset($color); 
/* ensure that following writes to
$color will not modify the last array element */

print_r($colors);
$color='hello';
print_r($colors);

输出:

Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)
Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => hello
)

https://eval.in/897010

【讨论】:

以上是关于为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?的主要内容,如果未能解决你的问题,请参考以下文章

为啥声明表变量与临时表相比非常慢?

为啥在 BigQuery 中取消嵌套两个或多个变量时没有得到任何结果?

为啥我们在 NSManagedObject 中需要临时 ID

为啥我应该“将 myVariable 转换为最终的一个元素数组”?

为啥我应该“将 myVariable 转换为最终的一个元素数组”?

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