當前位置:學者齋 >

計算機 >php語言 >

深入PHP變量存儲的詳解

深入PHP變量存儲的詳解

文章是對PHP變量的存儲進行了詳細的分析介紹,需要的朋友參考下,就跟隨本站小編一起去了解下吧,想了解更多相關信息請持續關注我們應屆畢業生考試網!

深入PHP變量存儲的詳解

  1.1.1 zval結構

Zend使用zval結構來存儲PHP變量的值,該結構如下所示:

複製代碼 代碼如下:

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;

struct _zval_struct {

/* Variable information */

zvalue_value value; /* value */

zend_uint refcount;

zend_uchar type; /* active type */

zend_uchar is_ref;

};

typedef struct _zval_struct zval;

Zend根據type值來決定訪問value的哪個成員,可用值如下:

IS_NULL

N/A

IS_LONG

對應

IS_DOUBLE

對應

IS_STRING

對應

IS_ARRAY

對應

IS_OBJECT

對應

IS_BOOL

對應.

IS_RESOURCE

對應

根據這個表格可以發現兩個有意思的地方:首先是PHP的數組其實就是一個HashTable,這就解釋了為什麼PHP能夠支持關聯數組了;其次,Resource就是一個long值,它裏面存放的通常是個指針、一個內部數組的x或者其它什麼只有創建者自己才知道的東西,可以將其視作一個handle。

  1.1.2 引用計數

引用計數在垃圾收集、內存池以及字符串等地方應用廣泛,Zend就實現了典型的引用計數。多個PHP變量可以通過引用計數機制來共享同一份zval,zval中剩餘的兩個成員is_ref和refcount就用來支持這種共享。

很明顯,refcount用於計數,當增減引用時,這個值也相應的遞增和遞減,一旦減到零,Zend就會回收該zval。

那麼is_ref呢?

  1.1.3 zval狀態

在PHP中,變量有兩種——引用和非引用的,它們在Zend中都是採用引用計數的方式存儲的。對於非引用型變量,要求變量間互不相干,修改一個變量時,不能影響到其他變量,採用Copy-On-Write機制即可解決這種衝突——當試圖寫入一個變量時,Zend若發現該變量指向的zval被多個變量共享,則為其複製一份refcount為1的zval,並遞減原zval的refcount,這個過程稱為“zval分離”。然而,對於引用型變量,其要求和非引用型相反,引用賦值的變量間必須是捆綁的,修改一個變量就修改了所有捆綁變量。

可見,有必要指出當前zval的狀態,以分別應對這兩種情況,is_ref就是這個目的,它指出了當前所有指向該zval的變量是否是採用引用賦值的——要麼全是引用,要麼全不是。此時再修改一個變量,只有當發現其zval的is_ref為0,即非引用時,Zend才會執行Copy-On-Write。

  1.1.4 zval狀態切換

標籤: PHP 存儲 變量
  • 文章版權屬於文章作者所有,轉載請註明 https://xuezhezhai.com/zh-hk/jsj/php/wkp3z5.html