Home  >  Article  >  Backend Development  >  PHP source code analysis: stored procedure decomposition of variables_PHP tutorial

PHP source code analysis: stored procedure decomposition of variables_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:26:30665browse

The PHP code is as follows:

Copy code The code is as follows:
$php_var = 1;

The corresponding code for C is:

Copy code The code is as follows:
zval* c_var; //Define PHP variable pointer
MAKE_STD_ZVAL(c_var); //Initialize PHP variables
ZVAL_LONG(c_var,1);//Assignment
ZEND_SET_SYMBL( EG(active_symbol_table), " php_var ", c_var);//Register to the global variable symbol table

1. First look at the first line: zval* c_var;//Declare a zval pointer c_var; The structure of zval is as follows:

Copy code The code is as follows:

struct _zval_struct {
/* Variable information */
zvalue_value value; /* The value of the variable */
zend_uint refcount; /* Reference counting, used during garbage collection */
zend_uchar type; /* Variable type */
zend_uchar is_ref; /* Is it a reference variable? */
};
typedef struct _zval_struct zval;

The structure of the value zvalue_value is as follows:

Copy code The code is as follows:

typedef union _zvalue_value {
long lval; /* Long shaping*/
Double dval; /* Double precision type */
struct { struct { /* string type value */
char *val; char *val;
int len;
} str;
HashTable *ht; /* Array type value */
zend_object_value obj; /*Value of object type*/
} zvalue_value;

2. Next, look at the second line: MAKE_STD_ZVAL(new_val);//Variable initialization. The relevant macros are as follows: //Initialization

Copy code 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)->refcount = 1;
(z)->is_ref = 0;

After expansion:

Copy code The code is as follows:
(c_var) = (zval *) emalloc(sizeof(zval)); //Allocate memory
(c_var)-> refcount = 1; //Reference count initialization
(c_var)-> is_ref = 0; //Whether to quote

You can see that its function is to allocate memory, initialize refcount, is_ref

3. Let’s look at the third line ZVAL_LONG(c_var,1). The related macro is:

Copy code The code is as follows:
//Define 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) (zval).type
#define Z_LVAL_P(zval_p) Z_LVAL(*zval_p)
#define Z_LVAL(zval) (zval).value.lval

Expanded to:

Copy code The code is as follows:

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

Four: Next, look at the fourth line: ZEND_SET_SYMBOL( EG(active_symbol_table), “php_var”, c_var); First, let’s explain that PHP variables are stored in a hashtable

Copy code 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, and the value is the pointer to the PHP variable, that is, the c_var pointer; the relevant macros are:

Copy code The code is as follows:

#define ZEND_SET_SYMBOL(symtable, name, var)                                              char *_name = (name); 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)->refcount; (var)->refcount; (var)->is_ref = 1; (var)->is_ref = 1;                if (_refcount) {                                            (var)->refcount += _refcount-1; (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);                                                            
        }                                                   
    }            

该函数的功能是:
1. 如果全局符号表已经存在该变量且是引用类型,则

a. 将原来变量的引用计数refcount,is_ref信息赋给c_var;
b. 释放掉原来变量zvalue的值,比如原来其值指向的是一个mysql连接资源,则释放该资源。
c. 将c_var指向的变量赋值给原来的变量 d. 释放c_var的内存空间 这样保证了,如果变量被应用,值一起改变。比如如果前面有$b=&a;

2. 如果全局符号表不存在该变量或者存在该变量但不是引用变量,则直接改变其值。

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/824657.htmlTechArticlePHP代码如下: 复制代码 代码如下: $php_var = 1; 对应C的代码是: 复制代码 代码如下: zval* c_var; //定义PHP变量指针 MAKE_STD_ZVAL(c_var); //初始化...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn