彻底搞懂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变量结构体,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!