PHP Bug还是我对语言的误解?

时间:2015-12-30 08:13:22

标签: php

这是我不理解的代码(作为输出)。

<?php
$x = ['test1', 'test2', 'test3', 'test4'];
echo "First FOREACH\n";
foreach ($x as &$y)
{
    echo $y."\n";
}
echo "\n\nSecond FOREACH\n";
foreach ($x as $y)
{
    echo $y."\n";
}

?>

输出:

First FOREACH
test1
test2
test3
test4

Second FOREACH
test1
test2
test3
test3

PS:我正在运行它:

php -v
PHP 5.6.11-1ubuntu3.1 (cli) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies

5 个答案:

答案 0 :(得分:5)

这更像是一个功能,它记录在foreach联机帮助页

  

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

在联机帮助页上有一些相关的评论,这是其中之一 http://php.net/manual/en/control-structures.foreach.php#111688

有关如何在此处发生这种情况的更多信息http://schlueters.de/blog/archives/141-References-and-foreach.html

答案 1 :(得分:5)

在第一个foreach语句之后,您$y指向最后一个数组项:

$x = ['test1', 'test2', 'test3', 'test4'];
$y =& $x[3];

每当您为$y分配值时,原始数组都将被修改。

当第二个foreach开始时,在每次迭代时,$x的下一个值都会被放入$y。因此,在每次迭代时,原始数组将如下所示:

// first iteration
$x = ['test1', 'test2', 'test3', 'test1'];
// second iteration
$x = ['test1', 'test2', 'test3', 'test2'];
// third iteration
$x = ['test1', 'test2', 'test3', 'test3'];
// fourth iteration
$x = ['test1', 'test2', 'test3', 'test3'];

答案 2 :(得分:0)

这是因为您的第一个循环,$y仍然是对最后一个数组项的引用,因此每次都会被覆盖。

当您在循环中使用引用时,建议使用unset()函数将其销毁。

对于假设,当您创建Global变量时,表示您正在创建引用。

还有一个例子,当我们在对象中使用$this关键字时,我们正在创建此对象的引用而不是再次复制。

答案 3 :(得分:0)

我说你得到类似的东西。

首先要做的 test1 test2 第二个要求 TEST1 TEST1

因为您正在使用&amp;在第一个foreach中使用$ y,这样你就可以使$ y引用$ x,整个数组$ x。 $ y将保留一个参考,直到你取消它为止 所以...
因为你在下一个foreach中重用了$ y,所以PHP将$ x设置为$ y的第一个元素,即&test;&#39; test1&#39;。 $ x将是[&#39; test1&#39;,&#39; test1&#39;]。

使用引用时一定要小心,并在不再需要它们时始终取消设置。

答案 4 :(得分:0)

好的我觉得它是这样的:

第一次循环完成后数组中的最后一个元素仍然使用变量$y

引用

在完成第一个循环时想到你的数组:

['test1', 'test2', 'test3', &'test4']

请注意,我在最后一个元素中插入了&,因为它是变量引用$y

现在第二个循环开始了。 $x中的每个元素都将被引用为$y并记住数组$x中的最后一个元素仍然被循环中的变量$y引用。

因此,在第二个循环的每次迭代中都会修改数组$x中的最后一个元素。作为$y

['test1', 'test2', 'test3', &'test1'] <-- $y as being first element, notice that the last element is also $y ['test1', 'test2', 'test3', &'test2'] $y being 'test2' ['test1', 'test2', 'test3', &'test3'] $y as 'test3' ['test1', 'test2', 'test3', &'test3'] $y being the last element which is 'test3'