Analysis of the PHP principle of variable separation/reference (Variables separation) _php Tutorial

Source: Internet
Author: User
First, let's review the structure of Zval:
Copy CodeThe code is as follows:
struct _zval_struct {
/* Variable Information */
Zvalue_value value; /* Value */
Zend_uint RefCount;
Zend_uchar type; /* Active type */
Zend_uchar Is_ref;
};

The RefCount and Is_ref fields we've never introduced, we know PHP is a long-running server-side scripting interpreter. So for it, efficiency and resource occupancy is a very important measure, that is, PHP must try to describe the memory footprint, consider the following code:
Copy CodeThe code is as follows:
$var = "Laruence";
$var _dup = $var;
Unset ($var);
?>

The first line of code creates a string variable, requesting a size of 9 bytes of memory, saving the string "Laruence" and the end of a null (/0).
The second line defines a new string variable and "copies" the value of the Var variable to the new variable.
The third line unset variable var
Such code in our usual script is very common, if PHP for each variable assignment to re-allocate memory, copy data, then the above code to apply for 18 bytes of memory space, and we can easily see that the above code in fact there is no need to apply for two space, hehe, PHP developers also see:
As we've said before, variables in PHP are implemented with a symbolic name stored in symbol_table, corresponding to a zval, such as the first line of code above, which stores a value "Var" in symbol_table, corresponding to a pointer to a ZVAL structure, The variable value "Laruence" is saved in this zval, so it is not difficult to imagine, for the above code, we can completely let "var" and "var_dup" corresponding pointers to the same zval.
PHP does the same, and at this point we need to introduce the RefCount field in the zval structure that we've never introduced before.
RefCount, as the name implies, records the current count of Zval being referenced.
For example, for code:
Copy CodeThe code is as follows:
$var = 1;
$var _dup = $var;
?>

The first line creates an shaping variable with a variable value of 1. At this point, the refcount of the Zval 1 is saved as 1.
In the second line, a new shaping variable is created, and the variable points to the zval you just created, and adds 1 to the Zval RefCount, at which point the refcount of this zval is 2.
PHP provides a function to help us understand the process debug_zval_dump:
Copy CodeThe code is as follows:
$var = 1;
Debug_zval_dump ($var);
$var _dup = $var;
Debug_zval_dump ($var);
?>

Output:
Long (1) refcount (2)
Long (1) refcount (3

If you're surprised, Var's refcount should be 1?
We know that for simple variables, PHP wears parameters in the form of a pass-through value. That is, when the Debug_zval_dump ($var) is executed, the $var is passed to debug_zval_dump in the form of a value, which will result in Var refcount plus 1, so as long as we can see that when the variable is assigned to a variable, can lead to Zval refcount plus 1 This fact can.
Now we look back at the code at the beginning of the article, what happens when the last line unset ($var) is executed? Yes, both RefCount minus 1, on the code:
copy code code as follows:
!--? php $var = "Laruence";
$var _dup = $var;
Unset ($var);
Debug_zval_dump ($var _dup);
?

Output:
String (8) "Laruence" RefCount (2

But what about the following code?
Copy the Code code as follows:
$var = "Laruence";
$var _dup = $var;
$var = 1;
?>

Obviously after this code execution, $var _dup value should still be "laruence", then how is this implemented?
This is the copy on write mechanism of PHP:
PHP before modifying a variable, will first look at the refcount of this variable, if the RefCount is greater than 1,php will execute a separate routine, for the above code, when the execution to the third row, PHP found $var point to Zval refcount more than 1, Then PHP will copy a new zval out, the original zval refcount minus 1, and modify symbol_table, so $var and $var_dup separation (separation). This mechanism is called copy on write (when copying).
On the code test:
Copy the Code code as follows:
$var = "Laruence";
$var _dup = $var;
$var = 1;
Debug_zval_dump ($var);
Debug_zval_dump ($var _dup);
?>

Output:
Long (1) refcount (2)
String (8) "Laruence" RefCount (2

Now we know that when using variables to replicate, PHP is not a real copy, but instead point to the same structure to try to save overhead. So, what about the references in PHP?
Copy CodeThe code is as follows:
$var = "Laruence";
$var _ref = & $var;
$var _ref = 1;
?>

At the end of this code, the $var is also indirectly modified to 1, which is called (change on write: changed when writing). So how does ze know that this time the replication does not need to separation?
This is the time to use the Is_ref field in Zval:
For the above code, when the second line executes, the Zval represented by the $var RefCount becomes 2, and the Is_ref is set to 1.
To the third row, PHP first check var_ref represents the Zval is_ref field, if it is 1, then do not separate, the general logic is as follows:
Copy CodeThe code is as follows:
if ((*val)->is_ref | | (*val)->refcount<2) {
Do not execute separation
...;//process
}

However, the question comes again, what about the following code?
Copy CodeThe code is as follows:
$var = "Laruence";
$var _dup = $var;
$var _ref = & $var;
?>

For the above code, there is a pair of copy on write variables $var and $var_dup, and a pair of change on write mechanism variables to $var and $var_ref, how does this work?
When the second line is executed, as previously said, $var _dup and $var point to the same zval, RefCount is 2.
When the third line is executed, PHP discovers that the refcount of the zval to be manipulated is greater than 1, then PHP executes separation, separates the $var_dup, and $var and $var_ref do the change on write association. That is, refcount=2, is_ref=1;
Based on this analysis, we can get debug_zval_dump out of the results of RefCount to 1:
Copy CodeThe code is as follows:
$var = "Laruence";
$var _dup = & $var;
Debug_zval_dump ($var);
?>

Output:
String (8) "Laruence" RefCount (1

Detailed reasons, the reader you just a little analysis can be drawn, I will not someone else. ;)
This time we introduce the variable separation mechanism of PHP, and next time I will continue to introduce the parameters in the PHP script if it is received and outgoing in the extension.

http://www.bkjia.com/PHPjc/328119.html www.bkjia.com true http://www.bkjia.com/PHPjc/328119.html techarticle first, let's review the structure of Zval: The copy code is as follows: struct _ZVAL_STRUCT {/* Variable information */Zvalue_value value;/* value */zend_uint RefCount; Zend_uchar ...

  • Contact Us

    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.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.