PHP source code analysis-variable stored procedure decomposition-php instance

Source: Internet
Author: User
This article mainly introduces the storage process decomposition of PHP source code analysis variables. after the declaration of PHP variables, this article breaks down a series of actions behind the interpreter, for more information, see the following PHP code:

The code is as follows:

$ Php_var = 1;

The code corresponding to C is:

The code is as follows:

Zval * c_var; // defines the PHP variable pointer
MAKE_STD_ZVAL (c_var); // initialize the PHP variable
ZVAL_LONG (c_var, 1); // value assignment
ZEND_SET_SYMBL (EG (active_symbol_table), "php_var", c_var); // register with the global variable symbol table

I. first look at the first line: zval * c_var; // declare a zval pointer c_var; the structure of zval is as follows:

The code is as follows:


Struct _ zval_struct {
/* Variable information */
Zvalue_value value;/* Variable value */
Zend_uint refcount;/* reference count, used for garbage collection */
Zend_uchar type;/* variable type */
Zend_uchar is_ref;/* whether it is a reference variable */
};
Typedef struct _ zval_struct zval;

The structure of zvalue_value is as follows:

The code is as follows:


Typedef union _ zvalue_value {
Long lval;/* long integer */
Double dval;/* double precision type */
Struct {/* string type value */
Char * val;
Int len;
} Str;
HashTable * ht;/* array type value */
Zend_object_value obj;/* object type value */
} Zvalue_value;

II. Next, let's take a look at the second line: MAKE_STD_ZVAL (new_val); // variables related to macro initialization, as shown below: // Initialization

The code is as follows:


# Define MAKE_STD_ZVAL (zv )\
ALLOC_ZVAL (zv );\
INIT_PZVAL (zv );

# Define ALLOC_ZVAL (z )\
ZEND_FAST_ALLOC (z, zval, ZVAL_CACHE_LIST)

# Define ZEND_FAST_ALLOC (p, type, fc_type )\
(P) = (type *) emalloc (sizeof (type ))

# Define INIT_PZVAL (z )\
(Z)-> refcount = 1 ;\
(Z)-> is_ref = 0;


Expanded:

The code is as follows:


(C_var) = (zval *) emalloc (sizeof (zval); // allocate memory
(C_var)-> refcount = 1; // the reference count is initialized.
(C_var)-> is_ref = 0; // whether to reference

We can see that the function is to allocate memory and initialize refcount, is_ref

3. the macro related to ZVAL_LONG (c_var, 1) in the third row is as follows:

The code is as follows:


// Define the value
# Define ZVAL_LONG (z, l ){\
Z_TYPE_P (z) = IS_LONG ;\
Z_LVAL_P (z) = l ;\
}
# Define Z_TYPE_P (zval_p) Z_TYPE (* zval_p)
# Define Z_TYPE (zval). type
# Define Z_LVAL_P (zval_p) Z_LVAL (* zval_p)
# Define Z_LVAL (zval). value. lval

Expanded:

The code is as follows:


(* C_var). type = IS_LONG;
(* C_var). value = 1;

4. Next, let's look at the fourth line: ZEND_SET_SYMBOL (EG (active_symbol_table), "php_var", c_var). First, it indicates that the PHP variable exists in a hashtable

The code is as follows:


Struct _ zend_executor_globals {
....
HashTable symbol_table; // symbol table of global variables
HashTable * active_symbol_table; // symbol table of local variables
.....
};

The Key of Hashtable is the name of the variable, that is, php_var. The value is the pointer to the PHP variable, that is, the c_var pointer. the related macro is:

The code is as follows:


# Define ZEND_SET_SYMBOL (symtable, name, var )\{\
Char * _ name = (name );\
ZEND_SET_SYMBOL_WITH_LENGTH (symtable, _ name, strlen (_ name) + 1, var, 1, 0 );\
}
// The main implementation is the following function:
# Define ZEND_SET_SYMBOL_WITH_LENGTH (symtable, name, name_length, var, _ refcount, _ is_ref )\
{
Zval ** orig_var ;\
If (zend_hash_find (symtable, (name), (name_length), (void **) & orig_var) = SUCCESS \
& PZVAL_IS_REF (* orig_var )){\
(Var)-> refcount = (* orig_var)-> refcount ;\
(Var)-> is_ref = 1 ;\
If (_ refcount ){\
(Var)-> refcount + = _ refcount-1 ;\
}\
Zval_dtor (* orig_var );\
** Orig_var = * (var );\
FREE_ZVAL (var );\
} Else {\
(Var)-> is_ref = _ is_ref ;\
If (_ refcount ){\
(Var)-> refcount = _ refcount ;\
}\
Zend_hash_update (symtable, (name), (name_length), & (var), sizeof (zval *), NULL );\
}\
}

This function has the following functions:
1. if the global symbol table already has this variable and it is of reference type

A. assign the reference count refcount and is_ref information of the original variable to c_var;
B. release the zvalue of the original variable. for example, if the original value points to a mysql connection resource, the resource is released.
C. assign the variable pointed to by c_var to the original variable d. release the memory space of c_var to ensure that, if the variable is applied, the value changes together. For example, if $ B = &;

2. if the global symbol table does not exist or the variable does not reference the variable, the value is changed directly.

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.