在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)
我的两个问题是:
这段代码还能用吗?
如果是这样,你能解释一下(可能通过例子)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)