最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入PHP變量存儲的詳解

 更新時間:2013年06月13日 10:56:15   投稿:jingxian  
本篇文章是對PHP變量的存儲進行了詳細(xì)的分析介紹,需要的朋友參考下

1.1.1 zval結(jié)構(gòu)
Zend使用zval結(jié)構(gòu)來存儲PHP變量的值,該結(jié)構(gòu)如下所示:

復(fù)制代碼 代碼如下:

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根據(jù)type值來決定訪問value的哪個成員,可用值如下:
 

IS_NULL

N/A

IS_LONG

對應(yīng)value.lval

IS_DOUBLE

對應(yīng)value.dval

IS_STRING

對應(yīng)value.str

IS_ARRAY

對應(yīng)value.ht

IS_OBJECT

對應(yīng)value.obj

IS_BOOL

對應(yīng)value.lval.

IS_RESOURCE

對應(yīng)value.lval

根據(jù)這個表格可以發(fā)現(xiàn)兩個有意思的地方:首先是PHP的數(shù)組其實就是一個HashTable,這就解釋了為什么PHP能夠支持關(guān)聯(lián)數(shù)組了;其次,Resource就是一個long值,它里面存放的通常是個指針、一個內(nèi)部數(shù)組的index或者其它什么只有創(chuàng)建者自己才知道的東西,可以將其視作一個handle。

1.1.2 引用計數(shù)
引用計數(shù)在垃圾收集、內(nèi)存池以及字符串等地方應(yīng)用廣泛,Zend就實現(xiàn)了典型的引用計數(shù)。多個PHP變量可以通過引用計數(shù)機制來共享同一份zval,zval中剩余的兩個成員is_ref和refcount就用來支持這種共享。
很明顯,refcount用于計數(shù),當(dāng)增減引用時,這個值也相應(yīng)的遞增和遞減,一旦減到零,Zend就會回收該zval。
那么is_ref呢?

1.1.3 zval狀態(tài)
可見,有必要指出當(dāng)前zval的狀態(tài),以分別應(yīng)對這兩種情況,is_ref就是這個目的,它指出了當(dāng)前所有指向該zval的變量是否是采用引用賦值的——要么全是引用,要么全不是。此時再修改一個變量,只有當(dāng)發(fā)現(xiàn)其zval的is_ref為0,即非引用時,Zend才會執(zhí)行Copy-On-Write。

1.1.4 zval狀態(tài)切換
當(dāng)在一個zval上進行的所有賦值操作都是引用或者都是非引用時,一個is_ref就足夠應(yīng)付了。然而,世界總不會那么美好,PHP無法對用戶進行這種限制,當(dāng)我們混合使用引用和非引用賦值時,就必須要進行特別處理了。
情況I、看如下PHP代碼:

復(fù)制代碼 代碼如下:

<?php
$a = 1;
$b = $a;
$c = $b;
?>

這段代碼首先進行了一次初始化,這將創(chuàng)建一個新的zval,is_ref=0, refcount=1,并將a指向這個zval;之后是兩次非引用賦值,正如前面所說,只要把b和c都指向a的zval即可;最后一行是個引用賦值,需要is_ref為1,但是Zend發(fā)現(xiàn)c指向的zval并不是引用型的,于是為c創(chuàng)建單獨的zval,并同時將d指向該zval。
從本質(zhì)上來說,這也可以看作是一種Copy-On-Write,不僅僅是value,is_ref也是受保護的對象。
整個過程圖示如下:

情況II,看如下PHP代碼:

復(fù)制代碼 代碼如下:

<?php
$a = 1;
$b = &$a;
$c = &$b;
?>

這段代碼的前三句將把a、b和c指向一個zval,其is_ref=1, refcount=3;第四句是個非引用賦值,通常情況下只需要增加引用計數(shù)即可,然而目標(biāo)zval屬于引用變量,單純的增加引用計數(shù)顯然是錯誤的, Zend的解決辦法是為d單獨生成一份zval副本。
全過程如下所示:

1.1.5 參數(shù)傳遞
PHP函數(shù)參數(shù)的傳遞和變量賦值是一樣的,非引用傳遞相當(dāng)于非引用賦值,引用傳遞相當(dāng)于引用賦值,并且也有可能會導(dǎo)致執(zhí)行zval狀態(tài)切換。這在后面還將提到。

相關(guān)文章

最新評論

安图县| 西城区| 手游| 呼伦贝尔市| 吉安县| 子长县| 留坝县| 宁南县| 临桂县| 武冈市| 县级市| 南江县| 龙门县| 虞城县| 东阳市| 温宿县| 桂林市| 临汾市| 广灵县| 临潭县| 兴仁县| 珠海市| 南陵县| 英吉沙县| 阿拉善右旗| 鞍山市| 册亨县| 黑龙江省| 奇台县| 崇义县| 缙云县| 乡城县| 乌兰察布市| 淮阳县| 开远市| 沂水县| 永胜县| 抚宁县| 石台县| 博湖县| 定襄县|