$a = 1;
$b = &$a;
$c = $b;
$c = 2;
c will not change the value of a
but
$x = 1;
$a = [1, &$x];
$b = $a;
$c = $b;
$c[1] = 2;
a will be change to [1,2]
Could anybody tell me why?
For the php doc and Are arrays in PHP passed by value or by reference?
Note that the assignment copies the original variable to the new one (assignment by value), so changes to one will not affect the other. This may also have relevance if you need to copy something like a large array inside a tight loop.
An exception to the usual assignment by value behaviour within PHP occurs with objects, which are assigned by reference. Objects may be explicitly copied via the clone keyword.
So both of your assignment is by value.
But in the array, the second store the referenc to x
, though the array is assigned by value, but the value of the second element of the array is also reference.
You can do, and the reference symbol &
is in the output
var_dump($a);
var_dump($c);
array(2) {
[0]=>
int(1)
[1]=>
&int(2)
}
array(2) {
[0]=>
int(1)
[1]=>
&int(2)
}
$b = &$a;
This is pass by reference and in other words, a new shallow copy of $a
. So, any modification in $b
will reflect in $a
and vice-versa.
Demo: https://3v4l.org/r86j4
$c = $b;
This is pass by value. So, any modification in $c
will only reflect in $c
.
$a = [1, &$x];
This is the same as the first example. The second location in the array is now a new copy of same $x
.
$x = 1;
$a = [1, &$x];
$b = $a;
$c = $b;
$c[1] = 2;
$b = $a
and $c = $b
above is pass by value. So, this assignment clones a new copy of $a
, however, the &$x
in the 2nd location is preserved.
That being said, it's never a good practice to assign variables as pass by reference to arrays individual locations(except for educational purposes). You would soon land into debugging issues and code's undefined behaviors.
All in all, if you want to create a new shallow copy, use &
, else use a simple assignment for deep copy(More info).
Update:
the 2nd location is preserved
because the second element is a reference, so it holds the reference and naturally the modification reflects everywhere. In the below example, it is pass by value.
<?php
$x = 4;
$y = &$x;
$a = [1,2,$y];
$b = $a;
$b[2] = 40;
var_dump($a);
var_dump($b);
Demo: https://3v4l.org/W9PIR