【发布时间】:2018-08-18 12:25:54
【问题描述】:
我在遍历数组时遇到了 PHP 中的异常行为,希望得到解释或确认这是一个错误。
对于初学者,这里是 PHP 版本:
PHP 7.2.3 (cli) (built: Mar 8 2018 10:30:06) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.3, Copyright (c) 1999-2018, by Zend Technologies
这是我为复制行为而创建的示例脚本:
<?php
$example = [
[
'a' => 'A',
'b' => 'B',
],
[
'c' => 'C',
'd' => 'D',
],
[
'e' => 'E',
'f' => 'F'
]
];
foreach ($example as &$letters) {
foreach ($letters as &$letter) {
// Do nothing
}
}
print_r($example);
foreach ($example as $letters) {
print_r($letters);
}
?>
这是输出:
Array
(
[0] => Array
(
[a] => A
[b] => B
)
[1] => Array
(
[c] => C
[d] => D
)
[2] => Array
(
[e] => E
[f] => F
)
)
Array
(
[a] => A
[b] => B
)
Array
(
[c] => C
[d] => D
)
Array
(
[c] => C
[d] => D
)
意外的行为是倒数第二个元素仅在数组的第二次迭代期间替换最后一个元素。但是,在打印整个数组时看不到这一点。
只有在嵌套的foreach 循环中,值被引用使用时才会发生这种情况。数组的长度似乎不会影响行为;最后一个元素总是替换为倒数第二个元素。
此外,如果在最后一个 foreach 循环之前添加 unset($letters); 语句,则问题似乎已解决。
这是故意的,还是 PHP 的错误?
编辑:请参阅上面的重复问题,特别是 this article,它直观地展示了为什么行为是这样的。
【问题讨论】:
-
您必须取消设置引用以避免该行为。如果我没记错的话,它在 foreach 的文档中。
-
php.net/manual/en/control-structures.foreach.php 检查粉红色的警告部分。
-
this question 的答案有一个链接,指向一篇说明该行为的文章。不过,它不被 PHP 视为错误。
-
阅读 PHP references.
-
我将其添加到此处的重复列表中。我不需要重新发明轮子。 :) 你知道,我说过“PHP 不认为它是一个错误”,但它真的不是一个错误。这只是使用这样的引用的非直观结果。