如果下面显示的PHP程序存储在bug.php中,则此命令
php bug.php
使用PHP 7.0.33-0ubuntu0.16.04.1(cli)(NTS)时将产生此输出 Zend Engine v3.0.0,版权所有(c)1998-2017 Zend Technologies Zend OPcache v7.0.33-0ubuntu0.16.04.1,版权所有(c)1999-2017,由Zend Technologies
输出:
Initial array
Array
(
[0] => aa
[1] => bb
)
j = 0 line = aa
element 0 is aa
j = 1 line = bb <----------------------------------------------
element 1 is ***bb <----------------------------------------------
Final array
Array
(
[0] => aa
[1] => ***bb
)
注意上面标记的行。元素$ A [1]是“ *** bb” $ line-foreach应该与键1关联的$ line是“ bb”。
这是一个错误,还是我不知道有PHP的细微之处?
<?php
$A = array
(
"aa",
"bb",
);
echo "Initial array\n";
print_r($A);
foreach ($A as $j => $line)
{
echo "j = $j line = $line\n";
echo "element $j is {$A[$j]}\n\n";
if ($j == 0)
$A[1] = "***" . $A[1];
}
echo "Final array\n";
print_r($A);
?>
答案 0 :(得分:0)
除非引用了数组,否则foreach()
将在指定数组的副本上操作,而不是对数组本身进行操作。 foreach对数组指针有一些副作用。在foreach期间或之后不要依赖数组指针而不重置它。
因此,当您修改$A[1]
时,您是在修改原始数组,而不是foreach()
循环随后使用的 copy 。
official documentation当前似乎没有这个重要的区别,但是您可以在此处了解更多信息:How does PHP 'foreach' actually work?
答案 1 :(得分:0)
如php.net上的注释中所述,除非引用了数组foreach
,否则操作的是指定数组的副本,而不是数组本身。您正在从原始副本输出变量,然后从更改后的数组输出。
答案 2 :(得分:0)
该数组作为副本传递到> s = "/path?first,,,second,,,third,value,,,fourth"
> s = s:gsub("^[^?]*%?", ""):gsub(",,,", "\0")
> for word in string.gmatch(s, "%Z+") do print(word) end
first
second
third,value
fourth
-除非您将其作为引用传递(通过向foreach
添加&
来表示)它不会反映您在第一次迭代中所做的值的更新。
请考虑以下问题:
$value
您看到foreach ($A as $j => &$line)
{
echo "j = $j line = $line\n";
echo "element $j is {$A[$j]}\n\n";
if ($j == 0)
$A[1] = "***" . $A[1];
}
/* Will output:
* j = 0 line = aa
* element 0 is aa
*
* j = 1 line = ***bb
* element 1 is ***bb
*/
表示我们正在向该块传递引用,现在任何更改都将反映到该数组,而不是您传递到循环块中的初始数组的&line
副本中
希望我很清楚...
我注意到文档说的恰好是
It says that exactly in documentation :)
为了能够直接在循环中修改数组元素,在$ value之前加&。在这种情况下,该值将通过引用分配。