// 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; // 用於 bool 類型、整型和資源類型
double dval; // 用於浮點類型
struct { // 用於字符串
char *val;
int len;
} str;
HashTable *ht; // 用於數組
zend_object_value obj; // 用於對象
zend_ast *ast; // 用於常量表達式(PHP5.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;複製代碼
多數文章,在提到PHP5 變量結構體的時候,都提到:sizeof(zval) == 24, sizeof(zvalue_value) == 16
,實際上這個論述並不許確,在 CPU 爲 64bit 時,這個結果是正確的。php
但當 CPU 爲32bit 時: sizeof(zval) == 16, sizeof(zvalue_value) == 8
,主要由於 CPU 爲 64bit 時,指針佔用8個字節,而 32bit時,指針爲4個字節。html
// 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的看似不少,但其實更簡單了,不論 CPU 是32bit 仍是 64bit,sizeof(zval) 永遠都是等於 16。
主要看 zend_value 中的 ww,是兩個 uint32_t,這個永遠是 8 個字節,因此 sizeof(zend_value) == 8,所以 sizeof(zval) == 16。node
因此 PHP7 新特性提到的節省內存這點上,在 32bit 系統中,PHP5 => PHP7 並沒有變化。數組
順便說下 sizeof,不能當作函數,雖然寫法像函數,這個數值會在編譯期就肯定好,非運行期。相似編譯預處理。函數
有關sizeof的詳情,能夠看:
blog.csdn.net/yangtalent1…ui
這個CSDN 文章的排版雖然有些亂,但總結的都是精華,耐心看完,理解透徹後,就很容理解我上面的分析。spa
原文:www.yinqisen.cn/blog-781.ht….net