PHP foreach循环不会更新值

时间:2019-03-04 20:29:35

标签: php foreach

如果下面显示的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);

?>

3 个答案:

答案 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之前加&。在这种情况下,该值将通过引用分配。