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。如果全局符号表没有变量或存在变量而不是引用变量,则它直接更改其值。