站長資訊網
        最全最豐富的資訊網站

        一起聊聊PHP7的基本變量

        變量的基礎結構

        我們都知道PHP的變量是弱類型的,聲明的時候無需指定類型。那么這里面具體是怎么實現的呢?這就得從變量的基礎結構說起了。

        zval的實現

        在源碼文件 zend_type.h 中,可以看到 zval 的定義:

        typedef struct _zval_struct     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 */         uint32_t     extra;                /* not further specified */     } u2; }

        zval 的結構由一個保存變量類型的值或指針的 union 聯合體 zend_value 以及兩個 union 聯合體 u1 和 u2 組成

        • u1

        u1的作用是用來保存變量類型及其信息,其里面的字段用處如下:

        type:記錄變量類型。 即可通過 u2.v.type 來訪問到

        type_flags:對應變量特有類型的標記(如常量類型,需引用計數類型,不可變類型),不同類型的變量對應的 flag 不一樣。

        const_flags:常量類型的標記

        reserved:保留字段

        • u2

        u2 主要是輔助作用,由于結構體的內存對齊,所以 u2 的的這塊空間有或者沒有 u2 都是已經占據空間了,所以就利用起來。u2的輔助字段里面記錄了很多類型信息,這些信息對內部功能有很大的好處,或提升緩存友好性或減少了內存尋址的操作。這里介紹其中部分字段。

        next:用來解決哈希沖突問題(哈希沖突這個目前還不懂),記錄沖突的下一個元素位置。

        cache_slot:運行時緩存。在執行函數時會優先去緩存中查找,若緩存中沒有,再去全局的 function 表中查找。

        num_args:函數調用時傳入參數的個數

        access_flags:對象類的訪問標識,如public protected private 這些。

        • zend_value
        typedef union _zend_value {     zend_long         lval;                /* 整型*/     double            dval;                /* 浮點型 */     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;

        從 zend__value 中可以看出,long、double 類型直接存儲值,而其它類型都為指針,指向各自的結構。所以,由于 zval 這樣的結構,PHP 變量在聲明的時候不用顯示的指定其類型,因為不管你賦給變量什么類型的值,它都能幫你找到對應的存儲結構。

        以值為字符串的變量為例,其結構是這樣的:

        PHP5 與 PHP7 的 zval 結構對比

        • PHP5
        • PHP7

        可以看到 php7 的 zval 總的只占 16 個字節,相比 PHP5 的 zval 所占用的 48 個字節節省了很大的內存。

        此外,在 PHP5 中,所有的變量都在堆中申請,但是對于臨時變量來說,沒有必要在堆中申請。所以在 PHP7 中對此做了優化,臨時變量是直接在棧中申請的。

        常見變量類型

        下面介紹幾個常見類型的變量結構,其他

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 亚洲av无码成人精品国产| 亚洲国产精品成人AV无码久久综合影院| 国产韩国精品一区二区三区| 亚洲精品国产品国语在线| 久久国产综合精品五月天| 88国产精品无码一区二区三区 | 精品国产免费一区二区三区香蕉| 亚洲精品制服丝袜四区| 久久久久九国产精品| 国产69精品久久久久99| 精品久久一区二区| 成人国产精品一区二区网站| 久久99精品国产麻豆| 日韩精品少妇无码受不了| 亚洲精品自产拍在线观看| 婷婷成人国产精品| 精品乱子伦一区二区三区| 国产精品无码一区二区在线 | 精品在线免费观看| 91精品视频网站| 精品不卡一区二区| 国产成人久久精品一区二区三区 | 久久亚洲AV永久无码精品| 国内精品久久久久国产盗摄 | 一级成人精品h| 免费视频精品一区二区三区| 好吊妞视频精品| 日本精品不卡视频| 99爱在线视频这里只有精品| 91久久福利国产成人精品| 91精品视频在线| 国产亚洲精品不卡在线| 久久久久亚洲精品无码网址| 欧美日韩专区麻豆精品在线 | 日韩专区亚洲精品欧美专区| 国产精品综合久久第一页| 国产99精品一区二区三区免费| 91精品国产综合久久四虎久久无码一级| 精品国产麻豆免费人成网站| 91国内揄拍国内精品情侣对白| 高清日韩精品一区二区三区|