2

I would like to know how the side effects of assigning a PHP variable by reference works under the hood (note, I am asking about variable assignment, not passing an argument by reference to a function; like in C++, the two can be different, and PHP has programmed these two operations separately under the hood).

Basically, I am seeking an explanation for the following:

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

After the dummy variable is created, assigning to $b[0] will alter $a[0], even if the $dummyReferenceVariable is never used. Why?

7
  • Please don't post an incomplete question. Commented Feb 2, 2015 at 17:14
  • nikic.github.io/2012/03/28/… is a good start Commented Feb 2, 2015 at 17:17
  • So it looks like you're trying to formulate a canonical question/answer pair. For that to be of use, the question has to be good as well as the answer. The question as you have asked it is too broad, and in immediate danger of being closed. Commented Feb 2, 2015 at 17:24
  • I think my answer is relatively complete. Please let me know if I've omitted any important details, or if it can be improved. Thanks. Commented Feb 2, 2015 at 17:24
  • If you can edit the question to make it specific, it may survive closure or be a candidate for reopening if it does get closed. Commented Feb 2, 2015 at 17:26

1 Answer 1

2

To see how such side effects work, consider the following snippet:

$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);

I will illustrates what happens under the hood with the following diagrams (what happens internally when arrays are assigned-by-value is already covered by this post), whose example in its answer starts the same as this one although the question asked is a different one:

NOTE: In the diagrams orange links behave such that when the array the pointing array element belongs to is assigned, the corresponding array element in the array copy will point to the same location with copy-on-write disabled. On the other hand, black links indicate that when an array element is assigned the value will be copied to a new memory location (copy-on-write):

enter image description here

enter image description here

enter image description here

Just to make my point, here is the program's output:

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)
}


Note. This peculiarity only takes place when assigning references to array elements, as the following straightforward snippet confirms:

// 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

which outputs the following as expected:

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

Here is what happens under-the-hood in the above scalars case:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.