PHP變數在zend核心中的儲存方式
PHP中的變數可以儲存任何的資料類型,這是因為它是弱類型語言。但php是用C語言編寫的,C語言是強型別語言,每個變數都有固定的類型,不能隨意改變變數的類型(可以通過強制類型轉變,不過有可能出現問題),在zend引擎中是怎樣可以做到一個變數儲存任何類型的呢?
在zend/zend.h標頭檔中,會發現下面的結構體:
typedef struct _zval_struct zval;typedef union _zvalue_value { long lval; double dval; struct { char *val; int len; }str; HashTable *ht; zend_object_value obj;} zvalue_value ;struct _zval_struct { zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref;};
zval結構體就是通常用到的PHP變數在核心中的表達方式。在zval結構體中,可以看到4個成員變數,分別是:
zvalue_value value; //變數的值,PHP變數的值就儲存在這裡zend_uint refcount; //變數引用數,變數引用計算機zend_uchar type; //變數的類型zend_uchar is_ref; //變數是否被引用
zval結構體的value成員變數是一個zvalue_value聯合體,PHP能夠保持任何的結構類型就是因為這個聯合體 。從zvalue_value聯合體的成員變數中可以看到,不同類型會儲存到不同的成員變數中,這樣就實現了PHP變數可以儲存任何資料類型。例如,當變數是整數類型時,會儲存到value的lval成員變數中;當變數的類型是字串時,又會儲存到value的str成員變數中。
還有一個問題,就是zend引擎是怎麼知道這個變數儲存的是什麼類型呢?我們注意到,zval結構體中有個type成員變數,這個成員變數就是要儲存一個php變數的類型。
zend引擎定義了8中變數類型:
#define IS_NULL 0#define IS_LONG 1#define IS_DOUBLE 2#define IS_STRING 3#define IS_ARRAY 4#define IS_OBJECT 5#define IS_BOOL 6#define IS_RESOURCE 7
每一個宏定義對應php語言層的一種類型,例如當zval的type成員變數等於IS_STRING時(zval.type==IS_STRING),說明這個變數的類型是字串類型。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。