Home >Backend Development >PHP Tutorial >In-depth understanding of php variable structure

In-depth understanding of php variable structure

黄舟
黄舟Original
2017-10-12 09:11:363071browse

This article mainly introduces the relevant knowledge of PHP variable structure. The article mentions zval in PHP5 and zval in PHP 7. The code is simple and easy to understand. Friends in need can refer to it

zval 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;  // 用于 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;

Most articles, when mentioning the PHP5 variable structure, mention: sizeof(zval ) == 24, sizeof(zvalue_value) == 16. In fact, this statement is not accurate. When the CPU is 64bit, this 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 32bit, the pointer is 4 bytes.

zval 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;

Zval in PHP 7 seems to be many, but it is actually simpler Yes, no matter whether the CPU is 32bit or 64bit, sizeof(zval) is always equal to 16.

Mainly look at the ww in zend_value, which is two uint32_t. This is always 8 bytes, so sizeof(zend_value) == 8, so sizeof(zval) == 16.

So in terms of saving memory mentioned in the new features of PHP7, in 32bit systems, PHP5 => PHP7 has no change.


By the way, sizeof cannot be regarded as a function. Although it is written like a function, the value will be determined during the compilation period, not during the runtime. Similar to compilation preprocessing.

Summarize

The above is the detailed content of In-depth understanding of php variable structure. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn