Why are the results of these two ways of assignment different?

Php
Mar.17,2021

this is the difference between normal assignment and reference assignment. Ordinary assignment only passes the value of $a to $b, while the following reference assignment not only points $b to the same address space as $a, at this time, $b is $a, even now unset ($b), output is still output and its value is $a.


above is very common
below. & $a, which means let an all use the same address
$a = null; Assign this address a value of null, so what is printed is null
. It should be like this. Yes, it is. This is it.


clarify a concept first:

ordinary assignment, change one, the value of other variables remains the same;
reference variable assignment, change one, and the value of other variables changes accordingly.

Let's go into more detail:
in fact, this situation is all related to reference count .

We know that the container that stores variables in php is a container called zval . In addition to data values and types, this container also stores two pieces of information, one is is_ref , indicating whether the variable is a reference variable, and the other is refcount , which represents the number of variables. Next, look at the code:

look at your first kind

$a = new Per();
$b = $a;
$a = null;
In the second line of

, when you assign the assigned variable a to b , this is the mutual assignment between ordinary variables. So the is_ref flag will not change, while refcount will increment by + 1; because the values and data types of $an and $b are the same, it's okay to use the same zval container;

but when you change one of the values below, the original refcount on $a will be subtracted by one, and $b will use a new memory address to generate a new zval container.

look at the second type:

$a = new Per();
$b = &$a;
$a = null;

in this case, look at the second line. When there is a reference action, the is_ref identification in the $a variable will change from 0 to 1, indicating that the variable is a reference variable, while refcount will increment itself by + 1, indicating the number of variables in the container.

because you are using the same memory address, the same zval container, and the reference relationship. So if you change one value, the rest of the referenced values will change accordingly.

can be tested with the following code: is_ref and refcount some changes in ordinary variable assignment and reference assignment:

$a = 10;
xdebug_debug_zval('a');
$b = &$a;
xdebug_debug_zval('a');
$a = 20;
xdebug_debug_zval('a');



$a = 10;
xdebug_debug_zval('a');
$b = $a;
xdebug_debug_zval('a');
$a = 20;
xdebug_debug_zval('b');

I believe you will find something, above.


the first one is passed by value, passing the memory address of the object. The values of $an and $b point to the memory address of the object

the second is reference passing, passing the address of the variable. By learning the c/cPP language, we know that the variable itself needs a space to store its own address, and the value of $b points to the memory address of $a, so the second unset ($a) will destroy the memory allocated by the variable, while $b will find the memory address of the object through the address of $a. Without $a, it naturally points to an invalid memory address.

Menu