search

Home  >  Q&A  >  body text

php - Since foreach operates on a copy of the original array, why can it still change the original array when written like this?

The foreach loop uses a copy of the original array. Why can the original array be changed after reference assignment?

$aOriginArray为二维数组
Array
(
    [0] => Array
        (
            [test1] => 1
            [test2] => 2
        )
)
foreach($aOriginArray as &$aNewValue){
    //为原数组子数组添加一个元素
    $aNewValue['new'] = 3;
}
//经过foreach循环引用赋值方式修改数组后的结果
print_r($aOriginArray);
Array
(
    [0] => Array
        (
            [test1] => 1
            [test2] => 2
            [new]   => 3 
        )
)

This paragraph can prove that the foreach operation is a copy of the original array.
Moreover, the original array was lost halfway during synchronization. The internal pointer of the original array was only moved once.
Subsequent operations are all in

executed on the copy
$k = ['a','b','c'];

foreach($k as $t){
    echo "current:".current($k);
    echo "<br>";
    echo "foreach:".$t;
    echo "<br>";
}
输出的结果是:
current:b
foreach:a
current:b
foreach:b
current:b
foreach:c

When using reference assignment, the reference situation of the array is as follows


xdebug_debug_zval("k");

k:
(refcount=2, is_ref=1),

数组的引用计数为2,说明有两个变量指向同一个数组,is_ref值为1,说明数组被引用
也就是说foreach在引用赋值时操作的是原数组,此时没有产生数组的拷贝
foreach的第一个参数为原数组的别名

foreach($k as &$t){
    ...
}

当使用foreach($k as $t){...}不加引用
数组的引用情况如下
k:
(refcount=1, is_ref=0),

原数组仅有一个符号在指向且未被引用

Thank you very much for your patient answers

三叔三叔2717 days ago1073

reply all(4)I'll reply

  • 给我你的怀抱

    给我你的怀抱2017-06-22 11:55:30

    After you add the & symbol, you are not using a copy of the original array. Without the ampersand, it is indeed a copy of the original array. Adding the ampersand is equivalent to a pointer, just assign the name to it. So if you change your new array, the original array will also change.
    Since PHP 5, it is easy to modify the cells of an array by adding & before $value. This method assigns by reference rather than copying a value.

    <?php
    $arr = array(1, 2, 3, 4);
    foreach ($arr as &$value) {
        $value = $value * 2;
    }
    // $arr is now array(2, 4, 6, 8)
    ?>

    reply
    0
  • 習慣沉默

    習慣沉默2017-06-22 11:55:30

    After you add the address passing symbol &, $aNewValue becomes a pointer to each element in the array, which is equivalent to modifying the original array

    reply
    0
  • phpcn_u1582

    phpcn_u15822017-06-22 11:55:30

    PHP copies when writing, it just uses a new pointer to point to the value when copying,

    reply
    0
  • PHP中文网

    PHP中文网2017-06-22 11:55:30

    It is a reference to a variable. The two variables point to the same address. Operating the copy also modifies the original array

    reply
    0
  • Cancelreply