当前位置: 首页 > news >正文

彻底搞懂 PHP 变量结构体,多数文章观点不准确

PHP5 中的 zval

// 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 时,这个结果是正确的。

但当 CPU 为32bit 时: sizeof(zval) == 16, sizeof(zvalue_value) == 8,主要因为 CPU 为 64bit 时,指针占用8个字节,而 32bit时,指针为4个字节。

PHP 7 中的 zval

// 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。

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

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

有关sizeof的详情,可以看:
blog.csdn.net/yangtalent1…

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

原文:www.yinqisen.cn/blog-781.ht…

转载于:https://juejin.im/post/59df252c6fb9a04500020c0b

相关文章:

  • perl shift
  • Ovirt 笔记
  • Oracle rownum用法的归纳
  • windows 上rsync客户端使用方法
  • 高性能存储代表 NETGEAR ReadyDATA 5200评测报告
  • nginx日志所有HTTP状态及次数统计
  • 添加本地通知(UILocalNotification)以及添加系统组件滚动视图(UIScrollView)
  • HTTP协议具体解释
  • MySQL配置文件my.cnf 例子最详细翻译
  • 如何在Linux和windos中创建指定大小的文件
  • Google Talk Testing(早期版本)
  • 重温SportsStore项目所遇到的问题总结
  • curl 上传文件
  • 回老家
  • JS字符转为json对象
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • [译]前端离线指南(上)
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • Git 使用集
  • Github访问慢解决办法
  • linux学习笔记
  • oschina
  • Spring Cloud Feign的两种使用姿势
  • 判断客户端类型,Android,iOS,PC
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • # .NET Framework中使用命名管道进行进程间通信
  • (07)Hive——窗口函数详解
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (十五)使用Nexus创建Maven私服
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)人的集合论——移山之道
  • 、写入Shellcode到注册表上线
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • [20190113]四校联考
  • [C++]——带你学习类和对象
  • [C++数据结构](31)哈夫曼树,哈夫曼编码与解码
  • [CF226E]Noble Knight's Path
  • [CISCN 2019华东南]Web11
  • [CSS] 点击事件触发的动画
  • [EFI]DELL XPS13 9360电脑 Hackintosh 黑苹果efi引导文件