用引用理解foreach逻辑 - 为什么第一个元素被改为'two',第二个元素被改为'三',第三个被改为'three3'?

dar*_*a33 1 php

我试图理解引用如何工作的细节,但我试图遵循编程逻辑,这个代码在循环遍历数组时正在做什么.我正试图一步一步地了解正在发生的事情.

我已经阅读了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.
}
Run Code Online (Sandbox Code Playgroud)

输出是......

one1
two2
three3

Array
(
[1] => two
[2] => three
[3] => three3
)
Run Code Online (Sandbox Code Playgroud)

非常感谢你的帮助!!

Mar*_*ker 7

第一次通过循环

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"
Run Code Online (Sandbox Code Playgroud)

第二次通过循环

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"
Run Code Online (Sandbox Code Playgroud)

第三次循环

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"
Run Code Online (Sandbox Code Playgroud)

如果你使用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]
Run Code Online (Sandbox Code Playgroud)

第二次通过循环

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]
Run Code Online (Sandbox Code Playgroud)

第三次循环

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]
Run Code Online (Sandbox Code Playgroud)