zvals in PHP5
// 1. zval typedef struct _zval_struct { zvalue_value value; zend_uint refcount__gc; zend_uchar type; zend_uchar is_ref__gc; } zval; // 2. zvalue_value typedef union _zvalue_value { long lval; // for bool, int and resource types double dval; // for floating point types struct { // for strings char * val; int len; } str; HashTable *ht; // for arrays zend_object_value obj; // for object zend_ast *ast; // for constant expressions (only available in PHP 5.6) } zvalue_value; // 3. zend_object_value typedef struct _zend_object_value { zend_object_handle handle; const zend_object_handlers *handlers; } zend_object_value; // 4. zend_object_handle typedef unsigned int zend_object_handle;
Most articles, when referring to the PHP5 variable structure, all mention: sizeof(zval) == 24, sizeof(zvalue_value) == 16
, in fact, this discussion is not accurate, when the CPU is 64bit, the result is correct.
But when the CPU is 32bit: sizeof(zval) == 16, sizeof(zvalue_value) == 8
, mainly because when the CPU is 64bit, the pointer occupies 8 bytes, and when it is 32bit, the pointer is 4 bytes.
zvals in PHP 7
// 1. zval struct _zval_struct { zend_value value; /* value */ union { struct { ZEND_ENDIAN_LOHI_4 ( zend_uchar type, /* active type */ zend_uchar type_flags, zend_uchar const_flags, zend_uchar reserved) /* call info for EX(This) */ }v; uint32_t type_info; } u1; union { uint32_t next; /* hash collision chain */ uint32_t cache_slot; /* literal cache slot */ uint32_t lineno; /* line number (for ast nodes) */ uint32_t num_args; /* arguments number for EX(This) */ uint32_t fe_pos; /* foreach position */ uint32_t fe_iter_idx; /* foreach iterator index */ uint32_t access_flags; /* class constant access flags */ uint32_t property_guard; /* single property guard */ } u2; }; // 2. zend_value typedef union _zend_value { zend_long lval; /* long value */ double dval; /* double value */ 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_t w1; uint32_t w2; } ww; } zend_value;
PHP 7 seems to be a lot, but it is actually simpler, no matter whether the CPU is 32bit or 64bit, sizeof(zval) is always equal to 16.
Mainly look at ww in zend_value, which are two uint32_t, this is always 8 bytes, so sizeof(zend_value) == 8, so sizeof(zval) == 16.
Therefore, in terms of saving memory mentioned by the new features of PHP7, in 32bit systems, PHP5 => PHP7 has not changed.
By the way, sizeof cannot be used as a function. Although it is written like a function, this value will be determined at compile time, not at runtime. Similar to compilation preprocessing.
For more information on sizeof, see:
http://blog.csdn.net/yangtalent1206/article/details/7568541
Although the layout of this CSDN article is a bit messy, it summarizes the essence. After reading it patiently and thoroughly, it is easy to understand my analysis above.
Reprinted from: http://www.yinqisen.cn/blog-781.html