带有引用的 Foreach 导致数组的最后一个元素重复
Foreach with reference causing array's last element to repeat
我 运行 遇到了一个奇怪的问题,可以用这个片段重现它:
<?php
$arr = [];
for($i = 0; $i <= 3; $i++) {
$arr[] = [
$i
];
}
foreach ($arr as &$item) {
$item[] = $item[0];
}
foreach ($arr as $item) {
print_r($item);
}
它正在输出(注意最后一个元素已被其前一个元素的副本替换):
Array
(
[0] => 0
[1] => 0
)
Array
(
[0] => 1
[1] => 1
)
Array
(
[0] => 2
[1] => 2
)
Array
(
[0] => 2
[1] => 2
)
然而,这是预期的结果:
Array
(
[0] => 0
[1] => 0
)
Array
(
[0] => 1
[1] => 1
)
Array
(
[0] => 2
[1] => 2
)
Array
(
[0] => 3
[1] => 3
)
如果我使用 array_map
而不是第一个 foreach
,它会起作用:
<?php
$arr = [];
for($i = 0; $i <= 3; $i++) {
$arr[] = [
$i
];
}
$arr = array_map(function ($item) {
$item[] = $item[0];
return $item;
}, $arr);
foreach ($arr as $item) {
print_r($item);
}
在 PHP 8.0.0.
下测试
是什么导致了这种差异?是否缺少有关数组指针的内容?
$arr = [];
for($i = 0; $i <= 3; $i++) {
$arr[] = [
$i
];
}
/** Output
* $arr = [[0],[1],[2],[3]]
*/
在此 foreach 循环中,您只是选择项目的现有值并将其设置为引用项目的新索引
foreach ($arr as &$item) {
$item[] = $item[0];
}
$item的类型是数组,$item[0]指的是它的0索引
$item[] 表示当前引用的项目内的新数组索引。
在您的第一个示例中,$item
变量在循环完成后仍保留对 $arr
的最后一个值的 引用。
foreach ($arr as &$item) {
$item[] = $item[0];
}
如果你使用 print_r(get_defined_vars());
你可以看到数组中有一个名为 item
的键
foreach 末尾的 double 值的行为是 described here 并且建议使用 unset($item)
销毁指定的变量
您也可以使用不同的变量名。
使用array_map,回调得到一个按名称传递的函数参数,它绑定到函数作用域。
如果你 运行 print_r(get_defined_vars());
在使用 array_map 之后你可以看到没有名为 item
的键
我 运行 遇到了一个奇怪的问题,可以用这个片段重现它:
<?php
$arr = [];
for($i = 0; $i <= 3; $i++) {
$arr[] = [
$i
];
}
foreach ($arr as &$item) {
$item[] = $item[0];
}
foreach ($arr as $item) {
print_r($item);
}
它正在输出(注意最后一个元素已被其前一个元素的副本替换):
Array
(
[0] => 0
[1] => 0
)
Array
(
[0] => 1
[1] => 1
)
Array
(
[0] => 2
[1] => 2
)
Array
(
[0] => 2
[1] => 2
)
然而,这是预期的结果:
Array
(
[0] => 0
[1] => 0
)
Array
(
[0] => 1
[1] => 1
)
Array
(
[0] => 2
[1] => 2
)
Array
(
[0] => 3
[1] => 3
)
如果我使用 array_map
而不是第一个 foreach
,它会起作用:
<?php
$arr = [];
for($i = 0; $i <= 3; $i++) {
$arr[] = [
$i
];
}
$arr = array_map(function ($item) {
$item[] = $item[0];
return $item;
}, $arr);
foreach ($arr as $item) {
print_r($item);
}
在 PHP 8.0.0.
下测试是什么导致了这种差异?是否缺少有关数组指针的内容?
$arr = [];
for($i = 0; $i <= 3; $i++) {
$arr[] = [
$i
];
}
/** Output
* $arr = [[0],[1],[2],[3]]
*/
在此 foreach 循环中,您只是选择项目的现有值并将其设置为引用项目的新索引
foreach ($arr as &$item) {
$item[] = $item[0];
}
$item的类型是数组,$item[0]指的是它的0索引 $item[] 表示当前引用的项目内的新数组索引。
在您的第一个示例中,$item
变量在循环完成后仍保留对 $arr
的最后一个值的 引用。
foreach ($arr as &$item) {
$item[] = $item[0];
}
如果你使用 print_r(get_defined_vars());
你可以看到数组中有一个名为 item
foreach 末尾的 double 值的行为是 described here 并且建议使用 unset($item)
您也可以使用不同的变量名。
使用array_map,回调得到一个按名称传递的函数参数,它绑定到函数作用域。
如果你 运行 print_r(get_defined_vars());
在使用 array_map 之后你可以看到没有名为 item