【问题标题】:Understanding foreach logic with references - Why is the 1st element being changed to 'two', the 2nd to 'three', and the third to 'three3'?使用引用理解 foreach 逻辑 - 为什么将第一个元素更改为“二”,将第二个元素更改为“三”,将第三个元素更改为“三三”?
【发布时间】:2012-01-17 21:19:30
【问题描述】:

我试图了解引用如何工作的来龙去脉,但我在试图遵循这段代码在数组中循环时究竟在做什么的编程逻辑时遇到了困难。我试图一步一步地了解正在发生的事情。

我已通读 PHP.net 帖子,并了解在数组的 foreach 中使用引用时,您必须取消设置变量。我也明白下面的代码不是最好的代码。我只是将它用于学习目的,以遵循 php 解释器如何通过不同代码运行的编程流程逻辑。

我的问题是,如果我不取消设置($v),每次循环遍历这个数组时,这段代码会做什么,以使其输出以下内容?换句话说,它是如何一步一步地让数组以'two'作为第一个元素,'three'作为第二个元素,'three3'作为第三个元素?

$arr = array(1=>'one',2=>'two',3=>'three');

foreach($arr as $k=>$v){

   $v = &$arr[$k];
   $v .= $k;
   echo $v . "\n";
   //unset($v) .... if I use unset($v) here, then the resulting $arr is correct.
}

输出是...

one1
two2
three3

Array
(
[1] => two
[2] => three
[3] => three3
)

非常感谢您的帮助!

【问题讨论】:

标签: php


【解决方案1】:

第一次循环

foreach($arr as $k=>$v){ // Sets $v to a value of "one"
   $v =& $arr[$k];       //  Sets $v as a reference to $arr[1] ("one")
   $v .= $k;             //  Sets $v (and hence also $arr[1]) to "one1"

第二次循环

foreach($arr as $k=>$v){ //  Sets $v to a value of "two"... 
                         //      because $v is already set as a reference to $arr[1] from the previous loop, 
                         //      this changes $arr[1] to a value of "two"
   $v =& $arr[$k];       //  Sets $v as a reference to $arr[2] ("two")
                         //  It no longer references $arr[1] so $arr[1] will not be changed any further
   $v .= $k;             //  Sets $v (and hence also $arr[2]) to "two2"

第三次循环

foreach($arr as $k=>$v){ //  Sets $v to a value of "three"... 
                         //      because $v is already set as a reference to $arr[2] from the previous loop, 
                         //      this changes $arr[2] to a value of "three"
   $v =& $arr[$k];       //  Sets $v as a reference to $arr[3] ("three")
                         //  It no longer references $arr[2] so $arr[2] will not be changed any further
   $v .= $k;             //  Sets $v (and hence also $arr[3]) to "three3"

如果你使用 unset()

第一次循环

foreach($arr as $k=>$v){ // Sets $v to a value of "one"
   $v =& $arr[$k];       //  Sets $v as a reference to $arr[1] ("one")
   $v .= $k;             //  Sets $v (and hence also $arr[1]) to "one1"
   unset($v);            //  Unsets $v as a reference, it no longer points to $arr[1]

第二次循环

foreach($arr as $k=>$v){ //  Sets $v to a value of "two"... 
                         //      As $v is no longer set as a reference to $arr[1], 
                         //      this leaves $arr[1] unchanged by this loop
   $v =& $arr[$k];       //  Sets $v as a reference to $arr[2] ("two")
   $v .= $k;             //  Sets $v (and hence also $arr[2]) to "two2"
   unset($v);            //  Unsets $v as a reference, it no longer points to $arr[2]

第三次循环

foreach($arr as $k=>$v){ //  Sets $v to a value of "three"... 
                         //      As $v is no longer set as a reference to $arr[2], 
                         //      this leaves $arr[2] unchanged by this loop
   $v =& $arr[$k];       //  Sets $v as a reference to $arr[3] ("three")
   $v .= $k;             //  Sets $v (and hence also $arr[3]) to "three3"
   unset($v);            //  Unsets $v as a reference, it no longer points to $arr[3]

【讨论】:

  • +1 以获得最佳解释。此外,无需通过引用分配:ideone.com/4vkC7
  • 很好的答案,但社区最好关闭这个问题,因为它已经被多次回答过,即使是 :) stackoverflow.com/questions/4969243/strange-behavior-of-foreach
  • @webbiedave - 确实,我已经忘记了……那是不久前的事了
  • 你太棒了马克!!!你的解释正是我需要的!!!!对 stackoverflow.com 的 Koodoos !!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 2017-03-11
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
相关资源
最近更新 更多