`
wyk86485480
  • 浏览: 28630 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
文章分类
社区版块
存档分类
最新评论

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

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的详情,可以看:

http://blog.csdn.net/yangtalent1206/article/details/7568541

 

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

 

转自:http://www.yinqisen.cn/blog-781.html

 

 
分享到:
评论

相关推荐

    彻底搞懂PHP 变量结构体

    本文将深入解析PHP5和PHP7中变量结构体的细节,帮助你彻底理解PHP如何管理内存和数据类型。 在PHP5中,变量的核心结构体是`zval`。这个结构体包含了几个关键组成部分: 1. `zvalue_value`:这是一个联合体,用于...

    结构体变量的复制与比较

    ### 结构体变量的复制与比较 #### 一、引言 在计算机编程中,特别是C语言编程领域,结构体是一种非常重要的数据类型,它允许程序员将不同类型的数据组合在一起作为一个整体来处理。对于结构体变量的复制与比较,是...

    VC++结构体成员变量和方法

    本篇文章将深入探讨VC++中结构体的成员变量和方法,以及如何实现结构体成员的调用。 1. **结构体与类的区别** - 默认访问修饰符:在C++中,类的成员默认是私有的(private),而结构体的成员默认是公有的(public...

    结构体变量的初始化和使用

    根据给定的信息,本文将详细解释“结构体变量的初始化和使用”。首先,我们来了解一下结构体的基本概念、本例中的结构体定义及其初始化方法,随后深入探讨如何使用已定义的结构体变量。 ### 结构体基本概念 在C++...

    C语言程序设计:结构体.pptx

    结构体变量不能整体引用,只能引用变量成员;main() { struct student { int No; float score; } stu1,stu2; };结构体成员本身又是一个结构体类型,则需要找到最低一级的成员。 ;结构体数组的定义 定义:可以参照...

    c语言结构体变量课件

    ### C语言结构体变量知识点详解 #### 一、教学目标 **知识与技能:** 1. **学会和掌握结构体类型的定义方法和结构体变量的定义及初始化。** - 学习如何定义结构体类型及其变量,并了解如何正确地初始化这些变量...

    下面程序是定义一个结构体,并为其定义结构体变量,对其值输入、输出。

    本文将通过两个实验,展示结构体在程序设计中的应用,包括结构体的定义、结构体变量的声明和初始化、结构体成员的访问和操作。 实验 1:定义结构体和结构体变量 在实验 1 中,我们定义了一个名为 `worker` 的...

    快速复制结构体变量和类实例

    在编程中,尤其是在C++和C这样的语言中,快速复制结构体变量和类实例是一个常见的需求。这通常涉及到数据的高效拷贝,特别是在处理大量数据或频繁创建对象时。"内存拷贝"(也称为“浅拷贝”或“位拷贝”)是一种常用...

    结构体变量.cpp

    结构体变量.cpp

    结构体问题

    在C++编程语言中,结构体(Struct)是一种复合数据类型,它允许我们将多个不同类型的变量组合成一个单一的实体,使得数据管理更加方便。结构体是C++中实现数据封装的一种基本方式,尤其对初学者来说,理解并熟练运用...

    QT设置可变的全局变量

    定义一个结构体,里面包含你要公共使用的变量. 然后在主程序 new一个这个结构体的指针. 然后在每个界面类里定义一个这个结构体的指针. 然后在界面初始化时将你那个new出来的指针传递进界面. 这样每个界面都可以访问...

    结构体使用详解,与结构体如何嵌套使用

    结构体在计算机编程中是一种非常重要的数据类型,它允许开发者定义一种新的数据类型,这种类型可以包含不同类型的多个成员变量。本文将详细讲解结构体的声明、初始化以及成员变量的使用,并重点介绍结构体的嵌套使用...

    开辟空间存放结构体变量.zip_开辟空间存放结构体变量

    在C++编程中,结构体(struct)是一种用户自定义的数据类型,它允许我们将多个不同类型的变量组合成一个单一的实体。"开辟空间存放结构体变量"这个主题是C++初学者经常遇到的一个概念,主要涉及到内存管理和结构体...

    c++通过结构体(struct)全局变量在多线程中传递参数

    然而,在多线程环境中,全局变量可能会引发竞态条件,即多个线程同时读写同一变量,导致不可预测的结果。为了解决这个问题,我们需要同步机制,如互斥锁(mutexes)来确保同一时间只有一个线程能访问这些变量。 在...

    关于结构体指针类型的强制转换

    ### 结构体指针类型的强制转换 #### 一、引言 在STM32嵌入式系统的开发过程中,经常需要对硬件寄存器进行直接操作,以实现对GPIO(General Purpose Input/Output,通用输入输出)等外设的精确控制。在C语言编程中...

    ktv.rar_KTV_c语言小项目_全局变量_结构体

    在C语言编程中,"ktv.rar_KTV_c语言小项目_全局变量_结构体"这个标题揭示了一个关于C语言的实践项目,它涉及到KTV系统,并且特别提到了全局变量和结构体这两个核心概念。下面我们将深入探讨这两个知识点。 全局变量...

    C语言结构体的用法.ppt

    结构体变量不能整体引用,只能引用变量成员。引用方式为: ```c 结构体变量名 . 成员名 ``` 例如: ```c struct student stu1, stu2; stu1.num = 10; stu1.score = 85.5; stu1.score += stu2.score; stu1.age++; ```...

    查找结构体向量变量(Vectors, structs and find)

    在C++编程中,结构体(structs)是一种自定义数据类型,允许我们将多个相关变量组合成一个单一的实体。当这些结构体被组织成向量(vectors)时,我们能够创建动态的、可扩展的数据集合。"查找结构体向量变量...

    结构体 指针 运算符详细讲解PPT

    结构体由多个成员变量组成,每个成员变量可以是基本数据类型或结构体类型。结构体的应用极其广泛,如描述学生信息、图形、矩阵等。 结构体变量的定义与应用是结构体的基础知识。定义结构体变量需要使用struct关键字...

Global site tag (gtag.js) - Google Analytics