索鸟网

  1. 首页
  2. 彻底搞懂 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/yangtale...

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

php

来源地址:https://segmentfault.com/a/1190000011527440 版权归作者所有!

相关教程

  • 彻底搞懂 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 _
  • 结构体

    结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,叫做结构。 在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型。 1、定义与声明
  • C_结构体

    结构体详解目录: 结构体对齐步骤 结构体定义 访问结构体内成员 结构体初始化 结构体在项目中大量运用: 原来单纯的以为全是四字节对齐,其实不然。 1、结构体对齐步骤: 1)将结构体内所有数据成员的长度值相加,记为sum_a; 2)将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到和sum_a上,记为sum_b。对齐模数是#pragm
  • SIZEOF结构体

    运算符sizeof可以计算出给定类型的大小,对于32位系统来说,sizeof(char) = 1; sizeof(int) = 4。基本数据类型的大小很好计算,我们来看一下如何计算构造数据类型的大小。               C语言中的构造数据类型有三种:数组、结构体和共用体。   &nb
  • 结构体内存对齐

    结构是一个或多个变量的集合,这些变量可能为不同的类型,为了处理的方便而将这些变量组织在一个名字之下;下面先来看一个定义结构体的例子:#include <stdio.h> #include <stdlib.h> struct testType{     char first;
  • 数据结构-->结构体

    #include<stdio.h> #include<stdlib.h> #include<string.h> #define true 1 #define false 0 //使用struct可以聚合不同数聚类性的数据,结构表示的是数据项的集合,每条数据项由其类型和名称指定; struct { char name[
  • 结构体内存对齐

    为什么会出现内存对齐?    因为当CPU访问内存对齐的数据时,它的运行效率是非常高的。当CPU试图读取的数值没有正确的对齐时,CPU可以执行两种操作之一:产生一个异常条件;执行多次对齐的内存访问,以便读取完整的未对齐数据,若多次执行内存访问,应用程序的运行速度就会慢。所以计算机采用内存对齐的方式来存储数据。这是高效编程一种很重要的思想:以
  • 结构体传参数

    #include <iostream> using namespace std; struct Data { int age; string name; }; Data func(Data data) { data.age = 100; return data; } int main() { Data data1; func(data1); cout <