This article brings you the content of the PHP variable reference assignment and value assignment of the detailed introduction (code), there is a certain reference value, the need for friends can refer to, I hope to help you.
First, use Memory_get_usage () to see how much PHP memory is used
1. Transfer value Assignment
Define a variable $ A = range (0, 10000); Var_dump (Memory_get_usage ());//define variable B, assign the value of a variable to b$b = $a; Var_dump (Memory_get_usage ());// Modify A//cow:copy-on-write$a = range (0, 10000); Var_dump (Memory_get_usage ());
Output Result:
int (989768) int (989856) int (1855608)
Define a variable$a = range(0, 10000);
$b = $a;
Make a modification to a$a = range(0, 10000);
PHP Write-time replication mechanism (Copy-on-write, also abbreviated as COW)
As the name implies, a copy of the memory is actually copied at the time of writing to modify it.
Cow was first used in UNIX systems to optimize threading and memory usage, and was later widely employed in a variety of programming languages, such as STL for C + +.
In the PHP kernel, cow is also the main memory optimization tool.
When assigning a value to a variable by assigning a value to it, the new memory is not requested to hold the value of the new variable, but rather a single counter is used to share the memory. Only when the value of one of the references to a variable changes, the new space is requested to hold the value content to reduce the memory footprint.
In many scenarios, PHP uses cow for memory optimization. For example: multiple assignments of variables, function parameter transfer, and in the function body to modify the arguments and so on.
2. Reference Assignment
Define a variable $ A = range (0, 10000); Var_dump (Memory_get_usage ());//define variable B, assign a reference to the A variable to b$b = & $a; Var_dump (Memory_get_usage ( );//Change A to a $ A = range (0, 10000); Var_dump (Memory_get_usage ());
Output Result:
int (989760) int (989848) int (989840)
Define a variable$a = range(0, 10000);
Define variable B to assign a reference to the A variable to B$b = &$a;
Make a modification to a$a = range(0, 10000);
Second, use xdebug_debug_zval()
the view variable reference case
xdebug_debug_zval()
The information used to display the variable. The xdebug extension needs to be installed.
1. Transfer value Assignment
$a = 1;xdebug_debug_zval (' a ');//define variable B, assign the value of a to b$b = $a; Xdebug_debug_zval (' a '); Xdebug_debug_zval (' B ');/a writes $ A = 2; Xdebug_debug_zval (' a '); Xdebug_debug_zval (' B ');
Output Result:
A: (Refcount=1, Is_ref=0) =1a: (refcount=2, Is_ref=0) =1b: (refcount=2, Is_ref=0) =1a: (Refcount=1, Is_ref=0) =2b: ( Refcount=1, is_ref=0) =1
Defining variables$a = 1;
$a = 1;xdebug_debug_zval (' a ');
Output
A: (Refcount=1, is_ref=0) =1
refcount=1
Indicates the number of references to the memory address to which the variable is pointing becomes 1
is_ref=0
Indicates that the variable is not a reference
Define $b
the variable, $a
assign the value to $b
it,$b = $a;
$b = $a; Xdebug_debug_zval (' a '); Xdebug_debug_zval (' B ');
Output
A: (refcount=2, Is_ref=0) =1b: (refcount=2, is_ref=0) =1
refcount=2
Indicates the number of references to the memory address to which the variable is pointing becomes 2
is_ref=0
Indicates that the variable is not a reference
Write to $a
a variable$a = 2;
$a = 2;xdebug_debug_zval (' a '); Xdebug_debug_zval (' B ');
Output
A: (Refcount=1, Is_ref=0) =2b: (Refcount=1, is_ref=0) =1
Because of the cow mechanism, $a
when a variable is written, a new memory space is allocated for the variable to $a
store $a
The value of the variable.
The $a
number of references to the memory address at this point and $b
point is changed to 1.
2. Reference Assignment
$a = 1;xdebug_debug_zval (' a ');//define variable B, assign a reference to B$b = & $a; Xdebug_debug_zval (' a '); Xdebug_debug_zval (' B ');//A write operation $ A = 2;xdebug_debug_zval (' a '); Xdebug_debug_zval (' B ');
A: (Refcount=1, Is_ref=0) =1a: (refcount=2, Is_ref=1) =1b: (refcount=2, Is_ref=1) =1a: (refcount=2, Is_ref=1) =2b: ( refcount=2, is_ref=1) =2
Defining variables$a = 1;
$a = 1;xdebug_debug_zval (' a ');
Output
A: (Refcount=1, is_ref=0) =1
refcount=1
Indicates the number of references to the memory address to which the variable is pointing becomes 1
is_ref=0
Indicates that the variable is not a reference
Define $b
A variable, $a
assign a reference to $b
it,$b = &$a;
$b = & $a; Xdebug_debug_zval (' a '); Xdebug_debug_zval (' B ');
Output
A: (refcount=2, Is_ref=1) =1b: (refcount=2, Is_ref=1) =1
refcount=2
Indicates the number of references to the memory address to which the variable is pointing becomes 2
is_ref=1
Indicates that the variable is a reference
Write to $a
a variable$a = 2;
$a = 2;xdebug_debug_zval (' a '); Xdebug_debug_zval (' B ');
Output
A: (refcount=2, Is_ref=1) =2b: (refcount=2, Is_ref=1) =2
Because variables $a
and variables $b
point to the same memory address, they are actually referenced.
When you write to a variable, the value of the $a
memory space that you point to is directly modified, so $b
the value of the variable changes along with it.
Third, when the variable is referenced, unset () will only dereference, will not destroy the memory space
$a = 1; $b = & $a;//unset will only dereference, not destroy memory space unset ($b); Echo $a;
Output
1
Define $a
A variable and $a
assign a reference to the variable$b
$a = 1; $b = & $a;
Destroyed$b
Unset ($b);
Output$a
Although destroyed $b
, $a
the references and memory space still exist.
echo $a;
Output
1
Iv. in PHP, the object itself is a reference assignment
Class person{public $age = 1;} $p 1 = new Person;xdebug_debug_zval (' P1 '), $p 2 = $p 1;xdebug_debug_zval (' P1 '); Xdebug_debug_zval (' P2 '); $p 2->age = 2; Xdebug_debug_zval (' P1 '); Xdebug_debug_zval (' P2 ');
P1: (Refcount=1, is_ref=0) =class person {public $age = (refcount=2, is_ref=0) =1}p1: (refcount=2, is_ref=0) =class person {Public $age = (refcount=2, is_ref=0) =1}p2: (refcount=2, is_ref=0) =class person {public $age = (refcount=2, is_ref=0) =1 }P1: (refcount=2, is_ref=0) =class person {public $age = (refcount=1, is_ref=0) =2}p2: (refcount=2, is_ref=0) =class Perso n {Public $age = (refcount=1, is_ref=0) =2}
Instantiating an Object$p1 = new Person;
$p 1 = new Person;xdebug_debug_zval (' P1 ');
Output
P1: (Refcount=1, is_ref=0) =class person {public $age = (refcount=2, is_ref=0) =1}
refcount=1
Indicates the number of references to the memory address to which the variable is pointing becomes 1
is_ref=0
Indicates that the variable is not a reference
$p1
give the assignment to$p2
$p 2 = $p 1;xdebug_debug_zval (' P1 '); Xdebug_debug_zval (' P2 ');
Output
P1: (refcount=2, is_ref=0) =class person {public $age = (refcount=2, is_ref=0) =1}p2: (refcount=2, is_ref=0) =class person {Public $age = (refcount=2, is_ref=0) =1}
refcount=2
Indicates the number of references to the memory address to which the variable is pointing becomes 2
$p2
write to a property in age
$p 2->age = 2;xdebug_debug_zval (' p1 '); Xdebug_debug_zval (' P2 ');
Output
P1: (refcount=2, is_ref=0) =class person {public $age = (refcount=1, is_ref=0) =2}p2: (refcount=2, is_ref=0) =class person {Public $age = (refcount=1, is_ref=0) =2}
Because the object itself is a reference assignment in PHP. $p2
when you write to a property in age
, the value that points to the memory space is directly modified, so the value of the variable $p1
's age
property changes along with it.
Analysis of practical examples
/** * Write the output of the following program * * $d = [' A ', ' B ', ' C ']; * * foreach ($d as $k + $v) * {* $v = & $d [$k]; *} * * When the program runs, what is the value of the variable $d at the end of each cycle? Please explain. * What is the value of the variable $d after the execution of the program? Please explain. */
1. First cycle
Calculate foreach
$v
$d[$k]
The value of the entry,
$k = 0$v = ' A ' $d [$k] = $d [0] = ' a '
At this point, $v
and $d[0]
in memory to open up a separate space
! [$v and $d [0] Open a space in memory separately] (http://md.ws65535.top/xsj/201 ...
$v = &$d[0]
Changed the memory address that the $v points to
$v = & $d [0]
! [$v = & $d [0] changed the memory address of the $val Point] (http://md.ws65535.top/xsj/201 ...
The value $d after the first loop:
[' A ', ' B ', ' C ']
2. Second cycle
Entered foreach
$v
with a value of ' B ', which $v
points to the same memory address, and $d[0]
is referenced, so $d[0]
the value is modified to ' B '
$v = 'b'
=$d[0] = 'b'
! [$v = ' B ' and ' = ' $d [0] = ' B '] (http://md.ws65535.top/xsj/201 ...
Calculate the foreach
value at $d[$k]
the time of entry
$k = 1$d[$k] = $d [1] = ' B '
! [$d [2] = ' B '] (http://md.ws65535.top/xsj/201 ...
$v = &$d[1]
Changed the memory address that the $v points to
$v = & $d [1]
! [$v = & $d [1]] (http://md.ws65535.top/xsj/201 ...
$d
the value after the second loop
[' B ', ' B ', ' C ']
3. Third Cycle
Entered foreach
$v
with a value of ' C ', which $v
points to the same memory address, and $d[1]
is referenced, so $d[1]
the value is modified to ' C '
$v = 'c'
=$d[1] = 'c'
! [$v = ' c ' = = $d [1] = ' C '] (http://md.ws65535.top/xsj/201 ...
Calculate the foreach
value at $d[$k]
the time of entry
$k = 2$d[2] = ' C '
! [$d [2] = ' C '] (http://md.ws65535.top/xsj/201 ...
$v = &$d[2]
Changed the memory address that the $v points to
$v = & $d [2]
! [$v = & $d [2]] (http://md.ws65535.top/xsj/201 ...
Value after the third loop $d
[' B ', ' C ', ' C ']
4. Measurement
$d = [' A ', ' B ', ' C '];foreach ($d as $k = = $v) { $v = & $d [$k]; Print_r ($d);} Print_r ($d);
Output:
Array ( [0] = a [1] = b [2] = + c) Array ( [0] = b [1] = b [2] = c) Array (
[0] = b [1] = = C [2] = + c) Array ( [0] = b [1] = = C [2] = + c)