foreach的奇怪行为

Man*_*edi 42 php arrays foreach

<?php
  $a = array('a', 'b', 'c', 'd');

  foreach ($a as &$v) { }
  foreach ($a as $v) { }

  print_r($a);
?>
Run Code Online (Sandbox Code Playgroud)

我认为这是一个正常的程序,但这是我得到的输出:

Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => c
)
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释一下吗?

Mar*_*ker 91

这是详细记录的PHP行为请参阅php.net的foreach页面上的警告

警告

即使在foreach循环之后,$ value和最后一个数组元素的引用仍然存在.建议通过unset()销毁它.

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

foreach ($a as &$v) { }
unset($v);
foreach ($a as $v) { }

print_r($a);
Run Code Online (Sandbox Code Playgroud)

编辑

尝试逐步指导这里实际发生的事情

$a = array('a', 'b', 'c', 'd');
foreach ($a as &$v) { }   // 1st iteration $v is a reference to $a[0] ('a')
foreach ($a as &$v) { }   // 2nd iteration $v is a reference to $a[1] ('b')
foreach ($a as &$v) { }   // 3rd iteration $v is a reference to $a[2] ('c')
foreach ($a as &$v) { }   // 4th iteration $v is a reference to $a[3] ('d')

                          // At the end of the foreach loop,
                          //    $v is still a reference to $a[3] ('d')

foreach ($a as $v) { }    // 1st iteration $v (still a reference to $a[3]) 
                          //    is set to a value of $a[0] ('a').
                          //    Because it is a reference to $a[3], 
                          //    it sets $a[3] to 'a'.
foreach ($a as $v) { }    // 2nd iteration $v (still a reference to $a[3]) 
                          //    is set to a value of $a[1] ('b').
                          //    Because it is a reference to $a[3], 
                          //    it sets $a[3] to 'b'.
foreach ($a as $v) { }    // 3rd iteration $v (still a reference to $a[3]) 
                          //    is set to a value of $a[2] ('c').
                          //    Because it is a reference to $a[3], 
                          //    it sets $a[3] to 'c'.
foreach ($a as $v) { }    // 4th iteration $v (still a reference to $a[3]) 
                          //    is set to a value of $a[3] ('c' since 
                          //       the last iteration).
                          //    Because it is a reference to $a[3], 
                          //    it sets $a[3] to 'c'.
Run Code Online (Sandbox Code Playgroud)

  • @Manish Trivedi:请参阅**警告**部分,了解为什么会这样.你的程序没有任何问题. (3认同)
  • 很好的解释!谢谢:DI必须记住一个作为参考/重复,所有其他关于foreach参考的答案并不能解释它和你在这里做的一样好! (2认同)
  • 在您的`unset($ v);`中,为什么`$ v`可以在foreach的范围之外访问?:o (2认同)
  • @马克贝克谢谢你。你回答了我的问题。刚刚开始了解 PHP 的特性:) (2认同)