PHP源码分析之变量的存储过程分解
PHP代码如下: 代码如下: 对应C的代码是: 代码如下: 一.首先看第一行: zval* c_var;//申明一个zval指针c_var; zval的结构如下: 代码如下: 其中值zvalue_value的结构如下: 代码如下: 二.接下来看第二行: MAKE_STD_ZVAL(new_val);//变量初始化 相关宏如下: //初始化 代码如下: 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; 展开后为: 代码如下: refcount = 1; //引用计数初始化
(c_var)-> is_ref = 0; //是否引用
可以看到其作用就是分配内存,初始化refcount,is_ref 三.下面看第三行 ZVAL_LONG(c_var,1) 相关宏为: 代码如下: 展开后为: 代码如下: 四:接下来看第四行: ZEND_SET_SYMBOL( EG(active_symbol_table),“php_var”,c_var); 首先说明下PHP的变量是存在一个hashtable里的 代码如下: Hashtable的Key为变量的名称,即php_var,值为指向PHP变量的指针,即c_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,&(var),sizeof(zval *),NULL);
}
}
该函数的功能是: 1. 如果全局符号表已经存在该变量且是引用类型,则 a. 将原来变量的引用计数refcount,is_ref信息赋给c_var; b. 释放掉原来变量zvalue的值,比如原来其值指向的是一个mysql连接资源,则释放该资源。 c. 将c_var指向的变量赋值给原来的变量 d. 释放c_var的内存空间 这样保证了,如果变量被应用,值一起改变。比如如果前面有$b=&a; 2. 如果全局符号表不存在该变量或者存在该变量但不是引用变量,则直接改变其值。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |