php底層變量的實現

你們都知道php是一個弱類型的語言,變量的類型是隨着賦值的類型變化的,php的底層是用C寫的,C自己是一個強類型的語言,那php在底層是怎麼實現類型的呢?php

其實在底層,php是經過一個結構體來存儲全部的變量的。結構體以下:數組

typedef struct _zval_struct zval

typedef struct _zval_struct {
    /* Variable information */
    zvalue_value value;
    zend_uint refcount_gc;
    zend_uchar type;
    zend_uint is_ref_gc;
}

解釋一下幾個變量的意義:
zend_value value 儲存的值,此處是一個指針,指到一個union的指針。php自己的值就是存儲在這個聯合體中。
zend_uint is_refcount 存儲的是引用計數
zend_uchar type 存儲變量的類型。
zend_uint is_ref_gc 是不是引用傳值。函數

php中全部的結構都是從用這個結構實現的。其中最關鍵的字段就是裏面的type字段了。
type字段總共有7個值,分別是IS_NULL,IS_BOOL,IS_LONG,IS_DOUBLE,IS_STRING,ISARRAY,IS_OBJECT,IS_RESOURCE
這個裏面包含了全部的php基本類型:ui

    標量類型:
    複合類型:
    特殊類型:
IS_BOOL,IS_lONG,IS_DOUBLE,IS_STRINGIS_ARRAY,IS_OBJECTIS_RESOURCE,IS_NULL

zval結構根據不一樣的類型,其zval結構中的zval字段指向的聯合體中存儲不一樣的值.這個聯合體就是php中同一個變量能夠存儲不一樣的值的關鍵.結構以下:指針

typedef union _zval_value{
    long *lval;
    double *dval;
    struct {
        char *val;
        int len;
    }str;
    HashTable *ht;
    zend_object_value obj;
}

從這個結構裏能夠看出php中全部變量的痕跡:
    IS_BOOL(boolen),是存儲在lval裏面,和整數存儲師同樣的。這裏你們應該想到=====對於false0處理的不一樣之處了。
    IS_LONG(整型),存儲在lval
    IS_DOUBLE(浮點型),存儲在dval
    IS_STRING(字符串),存儲在str
    IS_ARRAY(數組),存儲在*ht哈希table中
    IS_OBJECT(對象),存儲在zend_object_value
    IS_NULL,NULL值在這個結構中不用存儲,直接在zval結構中的type字段進行判斷。code

簡單的介紹一下字符串的存儲:
字符串的在聯合體中使用結構體的形式出現,代碼以下:orm

struct {
    char *val;
    int len;
}str;

能夠看到,php在存儲字符串時,將字符串的內容和長度都存了起來,這是爲了不重複計算字符串的長度。php中的函數strlen,就是直接返回了這個長度。對象

相關文章
相關標籤/搜索