PHP 7更改为foreach:我是否仍然可以删除我正在迭代的数组中的项目?

use*_*ite 26 php php-7

PHP 7向后兼容的改变文件说,有关的foreach如下:

在默认的按值模式下使用时,foreach现在将对正在迭代的数组的副本进行操作,而不是对数组本身进行操作.这意味着在迭代期间对数组所做的更改不会影响迭代的值.

我试图理解这意味着什么,我的主要问题是这个代码在PHP 7中是否与PHP 5.6中的相同?

foreach($array as $elementKey => $element) {
    if ($element == 'x') {
        unset($array[$elementKey]);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的两个问题是:

  1. 这段代码还能用吗?

  2. 如果是这样,你能解释一下(可能通过例子)PHP 7中的这一新变化意味着什么吗?

编辑

我一直在重读这份文件声明.我认为这意味着,如果您更改数组中较低项的值,那么当您在迭代中找到这些项时,这些更改将不会存在.例:

$array = ['x', 'y', 'z'];

$new = [];

foreach($array as $element) {
    if ($element == 'x') {
        $array[2] = 'a';
    }

    $new[] = $element;
}

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

但是,当我运行这个例子时,它似乎没有显示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 */
Run Code Online (Sandbox Code Playgroud)

之前的参考数组的按值迭代是特殊情况.在这种情况下,没有发生重复,因此迭代期间对数组的所有修改都将由循环反映出来.在PHP 7这种特殊情况下消失:一个数组的传值迭代将始终保持对原有元素的工作,在循环过程中不考虑任何修改.

这个答案解释了罕见的"特殊情况",其中关于foreach在阵列副本上操作的版本之间的工作方式不同.

Mac*_*ity 23

这意味着你现在必须明确地说你要引用你现在正在迭代的数组.

但是,在您的示例代码中,您正在引用根数组,因此无论您是否通过引用传递它都将起作用.

<?php
$array = ['x', 'y', 'z'];

foreach($array as $elementKey => $element) {
    if ($element=='x') {
        unset($array[$elementKey]);
    }
}

var_dump($array); // lists 'y' and 'z'
Run Code Online (Sandbox Code Playgroud)

一个更好的例子.在这种情况下,我们在foreach没有引用的情况下更改其中的值.因此,本地更改将丢失:

<?php
$array = ['x', 'y', 'z'];

foreach($array as $element) {
    if ($element=='x') {
        $element = 'a';
    }
}

var_dump($array); // 'x', 'y', 'z'
Run Code Online (Sandbox Code Playgroud)

Vs通过引用,我们声明它$element是对数组元素的引用:

<?php
$array = ['x', 'y', 'z'];

foreach($array as &$element) {
    if ($element=='x') {
        $element = 'a';
    }
}

var_dump($array); // 'a', 'y', 'z'
Run Code Online (Sandbox Code Playgroud)

这是在不同版本的PHP上运行的此代码的演示.

  • @userlite请参阅http://stackoverflow.com/questions/10057671/how-does-foreach-actually-work/14854568#14854568,PHP 7部分>数组复制>第2段和以下示例. (3认同)
  • 实际上,这里的所有三个例子在5和7中都是相同的. (2认同)
  • 当然,我理解这个问题.我的观点更多的是,我只是不认为你的答案 - 尽管它的所有上升和被接受 - 实际上是问题的答案.它可能回答了一个不同的问题;-) (2认同)