彻底搞懂PHP 变量结构体
PHP5中的zval
//1.zval
typedefstruct_zval_struct{
zvalue_valuevalue;
zend_uintrefcount__gc;
zend_uchartype;
zend_ucharis_ref__gc;
}zval;
//2.zvalue_value
typedefunion_zvalue_value{
longlval;//用于bool类型、整型和资源类型
doubledval;//用于浮点类型
struct{//用于字符串
char*val;
intlen;
}str;
HashTable*ht;//用于数组
zend_object_valueobj;//用于对象
zend_ast*ast;//用于常量表达式(PHP5.6才有)
}zvalue_value;
//3.zend_object_value
typedefstruct_zend_object_value{
zend_object_handlehandle;
constzend_object_handlers*handlers;
}zend_object_value;
//4.zend_object_handle
typedefunsignedintzend_object_handle;
多数文章,在提到PHP5变量结构体的时候,都提到:sizeof(zval)==24,sizeof(zvalue_value)==16,实际上这个论述并不准确,在CPU为64bit时,这个结果是正确的。
但当CPU为32bit时:sizeof(zval)==16,sizeof(zvalue_value)==8,主要因为CPU为64bit时,指针占用8个字节,而32bit时,指针为4个字节。
PHP7中的zval
//1.zval
struct_zval_struct{
zend_valuevalue;/*value*/
union{
struct{
ZEND_ENDIAN_LOHI_4(
zend_uchartype,/*activetype*/
zend_uchartype_flags,
zend_ucharconst_flags,
zend_ucharreserved)/*callinfoforEX(This)*/
}v;
uint32_ttype_info;
}u1;
union{
uint32_tnext;/*hashcollisionchain*/
uint32_tcache_slot;/*literalcacheslot*/
uint32_tlineno;/*linenumber(forastnodes)*/
uint32_tnum_args;/*argumentsnumberforEX(This)*/
uint32_tfe_pos;/*foreachposition*/
uint32_tfe_iter_idx;/*foreachiteratorindex*/
uint32_taccess_flags;/*classconstantaccessflags*/
uint32_tproperty_guard;/*singlepropertyguard*/
}u2;
};
//2.zend_value
typedefunion_zend_value{
zend_longlval;/*longvalue*/
doubledval;/*doublevalue*/
zend_refcounted*counted;
zend_string*str;
zend_array*arr;
zend_object*obj;
zend_resource*res;
zend_reference*ref;
zend_ast_ref*ast;
zval*zv;
void*ptr;
zend_class_entry*ce;
zend_function*func;
struct{
uint32_tw1;
uint32_tw2;
}ww;
}zend_value;
PHP7的看似很多,但其实更简单了,不论CPU是32bit还是64bit,sizeof(zval)永远都是等于16。
主要看zend_value中的ww,是两个uint32_t,这个永远是8个字节,所以sizeof(zend_value)==8,因此sizeof(zval)==16。
所以PHP7新特性提到的节省内存这点上,在32bit系统中,PHP5=>PHP7并无变化。
顺便说下sizeof,不能当做函数,虽然写法像函数,这个数值会在编译期就确定好,非运行期。类似编译预处理。
总结
以上所述是小编给大家介绍的PHP变量结构体,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!