深入理解PHP內核(五)變量及數據類型


原文鏈接:http://www.orlion.ga/238/

編程語言的類型可以分為強類型和弱類型兩種,PHP是弱類型語言,但是C語言是強類型語言。在官網PHP實現內部,所有變量使用同一種數據結構(zval)來保存,這個結構表示PHP中的各種數據類型,它不僅包含變量的值,也包含變量的類型。這就是PHP弱類型的核心。

那zval結構是如何實現弱類型的呢?

 

一、PHP變量類型及存儲結構

 

    PHP在聲明和使用變量的時候,並不需要指明其數據類型,PHP是弱類型語言,但是PHP有類型,PHP有八中數據類型,可以分成三類:標量類型:boolean、integer、float(double) string;復合類型:array、object;特殊類型:resource、NULL

    C語言是如何實現PHP中的弱類型的呢?

 

1、變量存儲結構

    

    變量的值存儲到如下所示的zval結構體中,zval結構體定義在Zend/zend.h文件,其結構如下:

typedef struct _zval_struct zval;
...
struct _zval_struct {
    /* Variable information */
    zvalue_value value;     /* value */
    zend_uint refcount__gc;
    zend_uchar type;    /* active type */
    zend_uchar is_ref__gc;
};

zval結構體中有四個字段,其含義分別為:

屬性名 含義 默認值
refcount_gc 表示引用計數 1
is_ref_gc 表示是否為引用 0
value 存儲變量的值  
type 變量具體的類型  

    在PHP5.3之后,引入了新的垃圾回收機制,引用計數和引用的字段名改為refcout_gc和is_ref_gc在此之前為refcount和is_ref.

    變量的值存儲在另外一個結構體zvalue_value,值存儲見下面的介紹。

 

2、變量類型

    zval結構體的type字段就是實現弱類型最關鍵的字段了,type的值可以為:IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_OBJECT和IS_RESOURCE之一。除此之外和它們定義在一起的類型還有IS_CONSTANT、IS_CONSTANT_ARRAY。

 

二、變量的值存儲

 

    前面提到變量的值存儲在zvalue_value聯合體中,結構體定義如下:

typedef union _zvalue_value {
    long lval;                  /* long value */
    double dval;                /* double value */
    struct {
        char *val;
        int len;
    } str;
     HashTable *ht;              /* hash table value */
    zend_object_value obj;
} zvalue_value;

    各種類型的數據會使用不同的方法來進行變量值的存儲,其對應賦值方式如下:

一般類型:

 

變量類型  
boolean ZVAL_BOOL

布爾型/整型的變量值存儲於(zval).value.lval中,其類型也會

以相應的IS_*進行存儲

integer ZVAL_LONG
float ZVAL_DOUBLE Z_TYPE_P(z)=IS_BOOL/LONG;Z_LVAL_P(z)=(b)!=0;
null ZVAL_NULL

NULL值的變量值不需要存儲,只需要把(zval).type標為IS_NUL

Z_TYPE_P(z)=IS_NULL;

resource ZVAL_RESOURCE

資源類型的存儲與其他一般變量無異,但其初始化及存儲實現則不

同Z_TYPE_P(z) = IS_RESOURCE; Z_LVAL_P(z) = 1;

 

字符串

    字符串的類型標示和其他數據類型一樣,不過在存儲字符串時多了一個字符串長度的字段。

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

(存儲字符串長度是因為字符串的操作十分頻繁,有利於節省時間,是空間換時間的做法)

 

數組Array

    數組是PHP中最常用也是最強大變量類型。數組的值存儲在zvalue_value.ht字段中,它是一個HashTable類型的數據。PHP數組使用哈希表來存儲關聯數據。PHP的哈希表實現中使用了兩個數據結構HashTable和Bucket。PHP所有的工作都是由哈希表實現。

 

對象Object

    PHP的對象是一種復合型的數據,使用一種zend_object_value的結構體來存放,其定義如下

typedef struct _zend_object_value {
    zend_object_handle handle;  //  unsigned int„類型,EG(objects_store).object_buckets的索引
    zend_object_handlers *handlers;
} zend_object_value;

PHP的對象只有在運行時才會被創建,前面介紹了EG宏,這是一個全局結構體由於保存在運行時的數據。其中就包括了用來保存所有被創建的對象的對象池,EG(objects_store),而object對象值內容的zend_object_handle域就是當前對象在對象池中所在的索引,handlers字段則是將對象進行操作時的處理函數保存起來。

    

    PHP的弱變量容器的實現方式是兼容並包的形式體現。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com