Что не так с адресацией переменных в php?

Выполняю код по смыслу такого содержания:
<?php
$a['s'] = [
    ["name"=>"test1"],
    ["name"=>"test2"],
    ["name"=>"test3"],
    ];
foreach($a as $k=>&$v1){
    
}
$test = $a;
foreach($test['s'] as $k=>&$v2){
    if($v2['name'] == "test1"){
        $v2['value'] = "test4";
    }
}
echo '<pre>'.print_r($a,1).'</pre>';
Выводит:
Array
(
    [s] => Array
        (
            [0] => Array
                (
                    [name] => test1
                    [value] => test4
                )

            [1] => Array
                (
                    [name] => test2
                )

            [2] => Array
                (
                    [name] => test3
                )

        )

)
Почему переменная $a изменилась, если меняем только переменную $test? Что не так с адресацией в php?
2 часа выявлял ошибку :-(
Если убрать:
foreach($a as $k=>&$v1){
    
}
то все в порядке
Александр Туниеков
19 сентября 2022, 11:08
modx.pro
478
0
Поблагодарить автора Отправить деньги

Комментарии: 4

Алексей Смирнов
20 сентября 2022, 11:53
0
А если убрать у переменных &
foreach($a as $k=> $v1){
}
у вас код так же заработает как хотите. вы же по сути ссылку делаете на значения.
    Александр Туниеков
    20 сентября 2022, 19:25
    0
    Ну я в курсе, что так заработает. Я не в курсе почему неожиданно сработало так, что переменная которая вроде не менялась изменилась?
    вы же по сути ссылку делаете на значения.
    Можно поподробнее. Вот ссылка на значение &$v1. И с ней ничего не делаем. Вот ссылка на на значение &$v2. Там меняем переменную. Икак происходит что изменилась переменная которую не трогал?
    Нужный код я поправил, чтоб заработал. Хотелось бы понимание что происходит, чтоб не нарываться в будущем
      Алексей Смирнов
      20 сентября 2022, 20:47
      +1
      Все просто.
      в момент когда вы выставляете & система должна создать ссылку на значение. А для того чтобы это сделать нужно значение которое определилось в $a Тоже было ссылкой.
      таким образом теперь $a ссылается на массив в памяти, где частичная ссылка на элемент массива в итерации $v.
      Поэтому следующее действие $test = $a; просто копирует ссылку (или создает ссылку на тот же элемент памяти) на наш первый массив-со всеми значениями и в обоих переменных ссылка на один и тот же элемент в памяти. Далее, думаю понятно почему изменения в$v2 по сути являются изменением $a
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
4