彻底搞懂 PHP 变量结构体,多数文章观点不准确_PHP_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > PHP > 彻底搞懂 PHP 变量结构体,多数文章观点不准确

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

 2017/10/11 17:43:06  wyk86485480  程序员俱乐部  我要评论(0)
  • 摘要:PHP5中的zval//1.zvaltypedefstruct_zval_struct{zvalue_valuevalue;zend_uintrefcount__gc;zend_uchartype;zend_ucharis_ref__gc;}zval;//2.zvalue_valuetypedefunion_zvalue_value{longlval;//用于bool类型、整型和资源类型doubledval;//用于浮点类型struct{//用于字符串char*val;intlen;}str
  • 标签:PHP 文章

PHP5 中的 zval

?

class="java" name="code">// 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 变量结构体的时候,都提到:monospace; padding: 2px 4px; color: #c7254e; white-space: nowrap; background-color: #f9f2f4; border-radius: 4px;">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

?

发表评论
用户名: 匿名