2
$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?

nanasaki
  • 23
  • 2

2 Answers2

0

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)
}
LF00
  • 27,015
  • 29
  • 156
  • 295
0

$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

Community
  • 1
  • 1
nice_dev
  • 17,053
  • 2
  • 21
  • 35
  • Thank you so much!Is a thinking of foreach reference trap.But i still not understand about why 'the &$x in the 2nd location is preserved'. – nanasaki Sep 12 '19 at 03:50
  • @nanasaki Because it holds the reference. You can see that in the var_dump() [here](https://3v4l.org/YbFHn). I have added a pass by value in my answer for more clarity. – nice_dev Sep 12 '19 at 07:31
  • 1
    Got it! Thank you so much!! – nanasaki Sep 12 '19 at 10:13