PHP 7 对 foreach 的更改:我是否仍可以删除要迭代的它们数组中的项目?
PHP 7 向后不兼容的更改文档对 foreach 有以下说明:
在默认的按值模式下使用时,现在将对要迭代的数组的副本进行操作,而不是对数组本身进行操作。这意味着在迭代期间对数组所做的更改不会影响迭代的值。
foreach
我试图理解这意味着什么,我的主要问题是,这段代码在PHP 7中的工作方式是否与在PHP 5.6中相同?
foreach($array as $elementKey => $element) {
if ($element == 'x') {
unset($array[$elementKey]);
}
}
我的两个问题是:
此代码是否仍有效?
如果是这样,你能解释一下(也许通过例子)PHP 7中的这个新变化意味着什么吗?
编辑
我一直在重新阅读文档声明。我认为这意味着,如果您更改数组中较低位置的项目的值,那么当您在迭代中到达这些项目时,这些更改将不存在。例:
$array = ['x', 'y', 'z'];
$new = [];
foreach($array as $element) {
if ($element == 'x') {
$array[2] = 'a';
}
$new[] = $element;
}
print_r($new);
但是,当我运行此示例时,它似乎在PHP版本中没有任何差异(尽管我以前从未使用过此工具,因此我不确定它是如何工作的)。
我意识到,如果我通过参考来做,我会得到一个新的。否则我不会。但两个版本似乎都是如此。a
我真正需要知道的是什么是不兼容性(通过示例)?
编辑 2
@NikiC建议的答案链接提供了我正在寻找的故事的其余部分:
在大多数情况下,此更改是透明的,除了更好的性能之外,没有其他影响。但是,有一种情况会导致不同的行为,即数组事先是引用的情况:
$array = [1, 2, 3, 4, 5];
$ref = &$array;
foreach ($array as $val) {
var_dump($val);
$array[2] = 0;
}
/* Old output: 1, 2, 0, 4, 5 */
/* New output: 1, 2, 3, 4, 5 */
以前,引用数组的按值迭代是特例。在这种情况下,不会发生重复,因此循环将反映迭代期间数组的所有修改。在 PHP 7 中,这种特殊情况已经消失:数组的按值迭代将始终在原始元素上工作,而不考虑循环期间的任何修改。
这个答案解释了罕见的“特殊情况”,在这种情况中,在对数组的副本进行操作时,版本之间的工作方式不同。foreach