PHP: Побочные эффекты назначения переменной элемента массива по ссылке

Я хотел бы знать, как побочные эффекты назначения переменной PHP по ссылке работают под капотом (обратите внимание, я спрашиваю о назначении переменной, не передавая аргумент по ссылке на функцию; как в C ++, эти два могут быть различными, и PHP запрограммировал эти две операции отдельно под капотом).

В основном, я ищу объяснение для следующего:

$a = array(111, 222, 333);
$dummyReferenceVariable = &$a[0];
$b = $a;
$b[0] = "change everything: both a[0] and b[0]";

После создания фиктивной переменной присваиваем $b[0] изменится $a[0]даже если $dummyReferenceVariable никогда не используется. Зачем?

2

Решение

Чтобы увидеть, как работают такие побочные эффекты, рассмотрите следующий фрагмент:

$a = array(111, 222, 333);
$b = $a;
$b[0] = 999;

var_dump($a, $b);

$dummyReferenceVariable = &$a[0];

$dummyReferenceVariable = 444;

var_dump($a, $b);

$c = $a;
$d = $b;

var_dump($a, $b, $c, $d);

$a[0] = 555;
$b[0] = 666;
$c[0] = 777;
$d[0] = 888;

var_dump($a, $b, $c, $d);

Я проиллюстрирую, что происходит под капотом, со следующими диаграммами (то, что происходит внутри, когда массивы назначаются по значению, уже покрыто эта почта), чей пример в своем ответе начинается так же, как этот, хотя заданный вопрос является другим:

ПРИМЕЧАНИЕ: на диаграммах оранжевые ссылки вести себя так, что когда массиву, к которому принадлежит указывающий элемент массива, назначен, соответствующий элемент массива в копии массива будет указывать на то же место с копирование при записи отключено. С другой стороны, черные ссылки указать, что при назначении элемента массива значение будет скопировано в новую ячейку памяти (копирование при записи):

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Просто, чтобы подчеркнуть, вот результат программы:

array(3) {
[0]=>
int(111)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(999)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(444)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(999)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(444)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(999)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(444)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(999)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(777)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(666)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
&int(777)
[1]=>
int(222)
[2]=>
int(333)
}
array(3) {
[0]=>
int(888)
[1]=>
int(222)
[2]=>
int(333)
}


Заметка. Эта особенность имеет место только при назначении ссылок на элементы массива, как подтверждает следующий простой фрагмент:

// ASSIGNING REFERENCE VALUES TO SCALARS (INSTEAD OF ARRAY ELEMENTS) WORK AS EXPECTED:

$a = 111;
$aRef = &$a;

$a = 222;
var_dump($a, $aRef); // 222, 222

$aRef = 333;
var_dump($a, $aRef); // 333, 333

$c = $a;
$d = $aRef;

$c = 444;
$d = 555;

var_dump($a, $aRef, $c, $d); // 333, 333, 444, 555

который выводит следующее, как и ожидалось:

int(222)
int(222)
int(333)
int(333)
int(333)
int(333)
int(444)
int(555)

Вот что происходит под капотом в вышеупомянутом случае скаляров:

введите описание изображения здесь

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector