当前位置: 首页 > 后端技术 > PHP

吃透PHP变量结构,大部分文章说的不准确

时间:2023-03-29 14:28:09 PHP

zvalinPHP5//1.zvaltypedefstruct_zval_struct{zvalue_valuevalue;zend_uintrefcount__gc;zend_uchar类型;zend_ucharis_ref__gc;}zval;//2.zvalue_valuetypedefunion_zvalue_value{longlval;//用于bool类型、整数类型和资源类型doubledval;//用于浮点类型struct{//用于字符串char*val;国际长度;海峡;哈希表*ht;//对于数组zend_object_valueobj;//对象zend_ast*ast;//用于常量表达式(仅限PHP5.6)}zvalue_value;//3.zend_object_valuetypedefstruct_zend_object_value{zend_object_handlehandle;constzend_object_handlers*handlers;}zend_object_value;//4.zend_object_handletypedefunsignedintzend_object_handle;大多数文章,在提到PHP5的变量结构时,提到:sizeof(zval)==24,sizeof(zvalue_value)==16,其实这个讨论是不准确的,当CPU是64bit时,结果是正确的。但是当CPU为32bit时:sizeof(zval)==16,sizeof(zvalue_value)==8,主要是因为CPU为64bit时,指针占用8字节,CPU为32bit时,指针占用4字节。PHP7中的zval//1.zvalstruct_zval_struct{zend_valuevalue;/*value*/union{struct{ZEND_ENDIAN_LOHI_4(zend_uchartype,/*activetype*/zend_uchartype_flags,zend_ucharconst_flags,zend_ucharreserved)/*EX(This)调用信息*/}v;uint32_t类型信息;}u1;union{uint32_t下一个;/*哈希冲突链*/uint32_tcache_slot;/*文字缓存槽*/uint32_tlineno;/*行号(对于ast节点)*/uint32_tnum_args;/*EX(This)的参数编号*/uint32_tfe_pos;/*foreach位置*/uint32_tfe_iter_idx;/*foreach迭代器索引*/uint32_taccess_flags;/*类常量访问标志*/uint32_tproperty_guard;/*单一属性守卫*/}u2;};//2.zend_valuetypedefunion_zend_value{zend_longlval;/*长值*/doubledval;/*双精度值*/zend_refcounted*counted;zend_string*str;zend_array*arr;zend_object*obj;zend_resource*res;zend_reference*ref;zend_ast_ref*ast;zval*zv;无效*指针;zend_class_entry*ce;zend_function*func;看起来很多,其实更简单。不管CPU是32bit还是64bit,sizeof(zval)总是等于16,主要看zend_value中的ww,是两个uint32_t,总是8字节,所以sizeof(zval)zend_value)==8,所以sizeof(zval)==16。因此,在PHP7的新特性中提到的节省内存方面,在32位系统中,PHP5=>PHP7没有变化。顺便说一下,sizeof不能看成是一个函数。虽然它写得像一个函数,但这个值将在编译时确定,而不是在运行时确定。类似于编译预处理。关于sizeof的详细介绍可以看:http://blog.csdn.net/yangtale...这篇CSDN文章虽然排版有点乱,但是总结就是精华。耐心看完,透彻理解我上面的分析就很容易理解了。