资讯专栏INFORMATION COLUMN

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

mtunique / 2770人阅读

摘要:中的用于类型整型和资源类型用于浮点类型用于字符串用于数组用于对象用于常量表达式才有多数文章,在提到变量结构体的时候,都提到,实际上这个论述并不准确,在为时,这个结果是正确的。主要看中的,是两个,这个永远是个字节,所以,因此。

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 文章的排版虽然有些乱,但总结的都是精华,耐心看完,理解透彻后,就很容理解我上面的分析。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30633.html

相关文章

  • PHP中全面阻挠SQL注入式进犯

    摘要:在这种状况下,虽然也只是规规矩矩地完成其缺省行为,可是的确能够维护你免于大多数简略的注入式进犯。年五月号,在登录代码中发现了一处注入软弱性。因而,它很容易遭受咱们前面所评论的注入类型的进犯。 或许存在许多不同类型的进犯动机,可是乍看上去,好像存在更多的类型。这是十分实在的-假如歹意用户发现了一个能够履行多个查询的方法的话。假如你的脚本正在履行一个SELECT指令,那么,进犯者能够逼迫显...

    lakeside 评论0 收藏0
  • PHP中全面阻挠SQL注入式进犯

    摘要:在这种状况下,虽然也只是规规矩矩地完成其缺省行为,可是的确能够维护你免于大多数简略的注入式进犯。年五月号,在登录代码中发现了一处注入软弱性。因而,它很容易遭受咱们前面所评论的注入类型的进犯。 或许存在许多不同类型的进犯动机,可是乍看上去,好像存在更多的类型。这是十分实在的-假如歹意用户发现了一个能够履行多个查询的方法的话。假如你的脚本正在履行一个SELECT指令,那么,进犯者能够逼迫显...

    zhkai 评论0 收藏0
  • 彻底搞懂 JS 中 this 机制

    摘要:的四种绑定规则的种绑定规则分别是默认绑定隐式绑定显示绑定绑定。绑定中的操作符,和其他语言中如的机制是不一样的。规则例外在显示绑定中,对于和的绑定将不会生效。它也是作为机制的一种替换,解决之前绑定过程各种规则带来的复杂性。 彻底搞懂 JS 中 this 机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 目录 t...

    李世赞 评论0 收藏0
  • 彻底搞懂elementUI指令与服务模式原理

    摘要:不甘做轮子的搬运工记录一个实习菜鸟写图片预览组件的艰辛道路很多组件中使用了指令模式和服务模式,比如以下以组件为例指令模式全屏覆盖服务模式跟大多数萌新一样,啥是服务先看看的目录结构打开目录,找到其下目录文件中有一大坨组件注册信息重点找 不甘做轮子的搬运工!!! 记录一个实习菜鸟写图片预览组件的艰辛道路~ elementUI很多组件中使用了指令模式和服务模式,比如:loading、mes...

    freewolf 评论0 收藏0
  • JS程序

    摘要:设计模式是以面向对象编程为基础的,的面向对象编程和传统的的面向对象编程有些差别,这让我一开始接触的时候感到十分痛苦,但是这只能靠自己慢慢积累慢慢思考。想继续了解设计模式必须要先搞懂面向对象编程,否则只会让你自己更痛苦。 JavaScript 中的构造函数 学习总结。知识只有分享才有存在的意义。 是时候替换你的 for 循环大法了~ 《小分享》JavaScript中数组的那些迭代方法~ ...

    melody_lql 评论0 收藏0

发表评论

0条评论

mtunique

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<