There are two ways to assign values in the PHP syntax: reference assignment, unreferenced assignment.
<?php
$a = 1;
$b = $a; Non-referential assignment
$c = & $b; Reference assignment
On the surface, it is often said that "reference assignment is two variables corresponding to the same variable (in C is actually a zval), unreferenced assignment is a direct result of a new variable (zval), while the value copy over."
This is a thought that can be figured out in most cases. (#1)
But in some cases it may seem very inefficient, for example: (#2)
<?php
function Print_arr ($arr) {//non-reference delivery
Print_r ($arr);
}
$test _arr = Array (
"A" => "a",
"B" => "B",
"C" => "C",
...
)//Here is a larger array
Print_arr ($test _arr);//First Call Print_arr function to perform output
Print_arr ($test _arr);//The second call to the Print_arr function to perform the output
If you follow the above approach (#1), then executing two times Print_arr, and it is not referenced, will produce two new variables exactly the same as $test_arr, and it will be very inefficient.
The actual code is running and does not produce two new variables. Because the PHP kernel has helped us to optimize.
How to achieve it? Here is the main point of this article: Reference counting & Copy-on-Write, it is the use of reference counting, write-time replication of the two mechanisms to optimize.
Before introducing the two mechanisms, understand one basic knowledge: How variables in PHP are represented in the kernel.
Variables defined in PHP are represented as a zval, and the definition of zval is defined in Zend/zend.h:
typedef struct _ZVAL_STRUCT Zval;
typedef Union _ZVALUE_VALUE {
Long lval; /* Long Value * *
Double Dval; /* Double Value * *
struct {
Char *val;
int Len;
} str;
HashTable *ht; /* Hash Table value * *
Zend_object_value obj;
} Zvalue_value;
struct _zval_struct {
/* Variable Information * *
Zvalue_value value; /* Value * *
Zend_uint RefCount;
Zend_uchar type; /* Active type */
Zend_uchar Is_ref;
};
Among them, RefCount and is_ref are the basis of the two mechanisms of implementing reference counting and writing.
RefCount the current variable stores the reference count, which is 1 when the Zval is initially created. Each additional reference is RefCount + +. When a reference is separated, the RefCount--。
Is_ref is used to indicate whether a zval is a reference state. In the case of zval initialization, it would be 0, indicating that it is not a reference.
<?php
$a;//a:refcount=1,is_ref=0, value=null;
$a = 1; A:refcount=2,is_ref=0, value=1;
$b = $a; a,b:refcount=3,is_ref=0,value=1;
$c = $a; a,b,c:refcount=4,is_ref=0,value=1;
$d = & $c; a,b:refcount=3,is_ref=0,value=1; C,d:refcount=1, Is_ref=1, value=1 the comment on the code above, indicating the changes refcount and Is_ref after the line was executed.
Copy on Write
PHP variables share data by reference counting, so what if you change the value of one of these variables?
When an attempt is made to write a variable, Zend finds that the variable points to a zval that is shared by multiple variables, copies a zval of Ref_count 1 and decrements the zval of the original RefCount, a process known as "Zval separation." Visible, only when there is a write operation Zend copy operation, so also known as Copy-on-write (write-time copy)
For reference variables, in contrast to the unreferenced type, the variable referencing the assignment must be bundled, and modifying a variable modifies all the bundle variables.
<?php
$a = 1;
$b = $a; Memory structure diagram during execution:
This article links http://www.cxybl.com/html/wlbc/Php/20130113/36056.html
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.