当前位置:首页 > PHP教程 > php高级应用 > 列表

彻底搞懂PHP 变量结构体

发布:smiling 来源: PHP粉丝网  添加日期:2021-08-12 10:23:09 浏览: 评论:0 

这篇文章主要介绍了PHP 变量结构体的相关知识,文中提到了PHP5中的 zval和PHP 7 中的 zval,代码简单易懂,需要的朋友可以参考下

PHP5 中的 zval

  1. // 1. zval 
  2. typedef struct _zval_struct { 
  3.  zvalue_value value; 
  4.  zend_uint refcount__gc; 
  5.  zend_uchar type; 
  6.  zend_uchar is_ref__gc; 
  7. } zval; 
  8. // 2. zvalue_value 
  9. typedef union _zvalue_value { 
  10.  long lval;  // 用于 bool 类型、整型和资源类型 
  11.  double dval; // 用于浮点类型 
  12.  struct {  // 用于字符串 
  13.   char *val; 
  14.   int len; 
  15.  } str; 
  16.  HashTable *ht; // 用于数组 
  17.  zend_object_value obj; // 用于对象 
  18.  zend_ast *ast; // 用于常量表达式(PHP5.6 才有) 
  19. } zvalue_value; 
  20. // 3. zend_object_value 
  21. typedef struct _zend_object_value { 
  22.  zend_object_handle handle; 
  23.  const zend_object_handlers *handlers; 
  24. } zend_object_value; 
  25. // 4. zend_object_handle 
  26. typedef unsigned int zend_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个字节。

PHP 7 中的 zval

  1. // 1. zval 
  2. struct _zval_struct { 
  3.  zend_value  value;   /* value */ 
  4.  union { 
  5.   struct { 
  6.    ZEND_ENDIAN_LOHI_4( 
  7.     zend_uchar type,   /* active type */ 
  8.     zend_uchar type_flags, 
  9.     zend_uchar const_flags, 
  10.     zend_uchar reserved)  /* call info for EX(This) */ 
  11.   } v; 
  12.   uint32_t type_info; 
  13.  } u1; 
  14.  union { 
  15.   uint32_t  next;     /* hash collision chain */ 
  16.   uint32_t  cache_slot;   /* literal cache slot */ 
  17.   uint32_t  lineno;    /* line number (for ast nodes) */ 
  18.   uint32_t  num_args;    /* arguments number for EX(This) */ 
  19.   uint32_t  fe_pos;    /* foreach position */ 
  20.   uint32_t  fe_iter_idx;   /* foreach iterator index */ 
  21.   uint32_t  access_flags;   /* class constant access flags */ 
  22.   uint32_t  property_guard;  /* single property guard */ 
  23.  } u2; 
  24. }; 
  25. // 2. zend_value 
  26. typedef union _zend_value { 
  27.  zend_long   lval;    /* long value */ 
  28.  double   dval;    /* double value */ 
  29.  zend_refcounted *counted; 
  30.  zend_string  *str; 
  31.  zend_array  *arr; 
  32.  zend_object  *obj; 
  33.  zend_resource *res; 
  34.  zend_reference *ref; 
  35.  zend_ast_ref  *ast; 
  36.  zval    *zv; 
  37.  void    *ptr; 
  38.  zend_class_entry *ce; 
  39.  zend_function *func; 
  40.  struct { 
  41.   uint32_t w1; 
  42.   uint32_t w2; 
  43.  } ww; 
  44. } zend_value; 

PHP 7的看似很多,但其实更简单了,不论 CPU 是32bit 还是 64bit,sizeof(zval) 永远都是等于 16。

主要看 zend_value 中的 ww,是两个 uint32_t,这个永远是 8 个字节,所以 sizeof(zend_value) == 8,因此 sizeof(zval) == 16。

所以 PHP7 新特性提到的节省内存这点上,在 32bit 系统中,PHP5 => PHP7 并无变化。

顺便说下 sizeof,不能当做函数,虽然写法像函数,这个数值会在编译期就确定好,非运行期。类似编译预处理。

Tags: PHP变量结构体

分享到: