找回密码
 立即注册

QQ登录

只需一步,快速开始

微信小程序综合交流

关注:51

所属分类: 微信开发 微信小程序综合交流

微信小程序用户交流版块,希望同学们积极发言,不过大家不要恶意发布广告哦!

[经验分享] 彻底搞懂 PHP 变量结构体,多数文章观点不准确

[复制链接]
查看: 60|回复: 0
最佳答案
0 

1

主题

1

帖子

112

积分

新人求带

积分
112
 楼主| 发表于 2017-10-12 14:47:12 | 显示全部楼层 |阅读模式
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,不能当做函数,虽然写法像函数,这个数值会在编译期就确定好,非运行期。类似编译预处理。


这个CSDN 文章的排版虽然有些乱,但总结的都是精华,耐心看完,理解透彻后,就很容理解我上面的分析。



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


易域网-您身边的域名管家

henkuai.com是专业的第三方微信开发者平台,为生态而生。


本站为第三方微信开发者平台,非腾讯官方网站。

天津市滨海新区
中新生态城中成大道生态建设公寓9号楼3层301

欢迎来这里一起喝喝茶,
聊聊你的产品。

微信公众号gongzhongkaifa

工作日12小时内回复。

广告推广
zhongcong@henkuai.com

工作日12小时内回复。

市场合作
songchang@henkuai.com