PHP源分析变量的存储过程分解

PHP代码如下所示:

复制代码如下:php_var = 1美元;

与C相对应的代码是:

复制下面的代码:zval * c_var; / /指针变量定义PHP

make_std_zval(c_var); / /初始化变量PHP

zval_long(c_var,1); / /分配

zend_set_symbl(如(active_symbol_table),php_var,c_var); / /注册到全局符号表

在第一行一看:zval *。c_var; / /声明一个指针指向一个变量c_var zval结构如下:

复制代码代码如下所示:

结构_zval_struct {

变量信息

zvalue_value价值; / *变量值

zend_uint引用计数; / *引用计数的垃圾回收利用。

zend_uchar型; / * * /变量类型

zend_uchar is_ref; / * * /参考变量

};

_zval_struct zval结构定义;



的价值zvalue_value结构如下:

复制代码代码如下所示:

_zvalue_value { typedef联盟

长的语句; / * * /长的塑料

双dval; / * * /双精度型

字符串类型结构的值。

字符*;

Int len;

STR };

哈希表* HT; / *值的数组类型

zend_object_value obj; / *值对象类型

Zvalue_value};



两。接下来的第二行:make_std_zval(new_val); / /相关宏观变量初始化如下: / /初始化

复制代码代码如下所示:

#定义make_std_zval(ZV)

alloc_zval(ZV);

init_pzval(ZV);



#定义alloc_zval(Z)

zend_fast_alloc(Z,zval,zval_cache_list)



#定义zend_fast_alloc(P,型,fc_type)

(P)=(类型*)emalloc(sizeof(类型))



#定义init_pzval(Z)

(Z)->引用计数= 1;

(Z)- > is_ref = 0;





展开后,它是:

复制代码代码如下所示:

(c_var)=(zval * emalloc)(sizeof(变量)); / /内存分配

(c_var)->引用计数= 1; / /初始化一个引用计数

(c_var)-> is_ref = 0; / /参考



可以看出,函数分配内存,初始化引用计数,is_ref

三。看看下面的zval_long第三线(c_var,1)相关的宏:

复制代码代码如下所示:

定义值

#定义zval_long(Z,L){

z_type_p(Z)= is_long;

z_lval_p(Z)= L;

}

#定义z_type_p(zval_p)z_type(* zval_p)

#定义z_type(机制)(zval类型)。

#定义z_lval_p(zval_p)z_lval(* zval_p)

#定义z_lval(机制)(机制)。value.lval



展开后,它是:

复制代码代码如下所示:

(* c_var型= is_long);

(* c_var值= 1);



四:下到第四线:zend_set_symbol(如(active_symbol_table),php_var,c_var);首先,它表明,下一个PHP变量是在哈希表中。

复制代码代码如下所示:

结构_zend_executor_globals {

的…

哈希表symbol_table; / /全局变量符号表

HashTable *active_symbol_table; / / local variable symbol table

的…

};



哈希表的关键是变量,即名php_var,PHP变量的指针,即指针的值,c_var;相关的宏:

复制代码代码如下所示:

#定义zend_set_symbol(symtable,名字,瓦尔河) {

char * _name =(名称);

zend_set_symbol_with_length(symtable,_name,strlen(_name)+ 1,VAR,1, 0);

}

为了实现主 /以下功能:

#define ZEND_SET_SYMBOL_WITH_LENGTH (symtable, name, name_length, VaR, _refcount, _is_ref)

{

zval ** orig_var;

如果(zend_hash_find(symtable,(姓名),(name_length),(void *)orig_var)= =成功

pzval_is_ref(* orig_var)){

(VaR)->引用计数=(* orig_var)->引用计数;

(VaR)-> is_ref = 1;

如果(_refcount){

(VaR)->引用计数= _refcount-1;

}

zval_dtor(* orig_var);

* orig_var = *(瓦尔河);

free_zval(瓦尔河);

{其他{

(VaR)-> is_ref = _is_ref;

如果(_refcount){

(VaR)->引用计数= _refcount;

}

zend_hash_update(symtable,(姓名),(name_length),(VAR),sizeof(zval *),null);

}

}



这个函数的功能是:

1。如果全局符号表已经存在这个变量,并且是一个引用类型,

A.计数的原始变量的引用计数的参考,并is_ref信息给c_var;

B.发布原始变量的值zvalue,例如,原来的值指向一个MySQL连接资源和释放资源。

C.分配由c_var对原始变量D.内存空间释放c_var变量,如果使用变量,改变价值联系在一起。例如,如果有一个$ =一个在它的前面;

2。如果全局符号表没有变量或存在变量而不是引用变量,则它直接更改其值。