亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

PHP內(nèi)核探索:變量存儲(chǔ)與類型使用說(shuō)明

 更新時(shí)間:2014年01月30日 22:45:59   作者:  
這篇文章主要介紹了PHP內(nèi)核探索:變量存儲(chǔ)與類型的相關(guān)資料,需要的朋友可以參考下

先回答前面一節(jié)的那個(gè)問(wèn)題吧。

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

<?php
    $foo = 10;
    $bar = 20;

    function change() {
        global $foo;
        //echo '函數(shù)內(nèi)部$foo = '.$foo.'<br />';
        //如果不把$bar定義為global變量,函數(shù)體內(nèi)是不能訪問(wèn)$bar的
        $bar = 0;
        $foo++;
    }

    change();
    echo $foo, ' ', $bar;
?>

程序輸出 11 20。原因是,方法內(nèi)部無(wú)法訪問(wèn)$bar變量,所以它的值還是20。使用global之后,可以取得$foo的值,自增后$foo的值就是11。
Global的作用是定義全局變量,但是這個(gè)全局變量不是應(yīng)用于整個(gè)網(wǎng)站,而是應(yīng)用于當(dāng)前頁(yè)面,包括include或require的所有文件。
前言中提到變量的三個(gè)基本特性,其中的有一個(gè)特性為變量的類型,變量都有特定的類型, 如:字符串、數(shù)組、對(duì)象等等。編程語(yǔ)言的類型系統(tǒng)可以分為強(qiáng)類型和弱類型兩種:
強(qiáng)類型語(yǔ)言是一旦某個(gè)變量被申明為某個(gè)類型的變量,則在程序運(yùn)行過(guò)程中,該不能將該變量的類型以外的值賦予給它 (當(dāng)然并不完全如此,這可能會(huì)涉及到類型的轉(zhuǎn)換,后面的小節(jié)會(huì)有相應(yīng)介紹),C/C++/Java等語(yǔ)言就屬于這類。
PHP及Ruby,JavaScript等腳本語(yǔ)言屬于弱類型語(yǔ)言:一個(gè)變量可以表示任意的數(shù)據(jù)類型。
PHP之所以成為一個(gè)簡(jiǎn)單而強(qiáng)大的語(yǔ)言,很大一部分的原因是它擁有弱類型的變量。 但是有些時(shí)候這也是一把雙刃劍,使用不當(dāng)也會(huì)帶來(lái)一些問(wèn)題。就像儀器一樣,越是功能強(qiáng)大, 出現(xiàn)錯(cuò)誤的可能性也就越大。
在官方的PHP實(shí)現(xiàn)內(nèi)部,所有變量使用同一種數(shù)據(jù)結(jié)構(gòu)(zval)來(lái)保存,而這個(gè)結(jié)構(gòu)同時(shí)表示PHP中的各種數(shù)據(jù)類型。 它不僅僅包含變量的值,也包含變量的類型。這就是PHP弱類型的核心。
那zval結(jié)構(gòu)具體是如何實(shí)現(xiàn)弱類型的呢,下面我們一起來(lái)揭開(kāi)面紗。
變量存儲(chǔ)結(jié)構(gòu)
PHP在聲明或使用變量的時(shí)候,并不需要顯式指明其數(shù)據(jù)類型。
PHP是弱類型語(yǔ)言,這并不表示PHP沒(méi)有類型,在PHP中,存在8種變量類型,可以分為三類
* 標(biāo)量類型:boolean、integer、float(double)、string
* 復(fù)合類型: array、object
* 特殊類型: resource、NULL
官方PHP是用C實(shí)現(xiàn)的,而C是強(qiáng)類型的語(yǔ)言,那這是怎么實(shí)現(xiàn)PHP中的弱類型的呢?
變量的值存儲(chǔ)到以下所示zval結(jié)構(gòu)體中。 zval結(jié)構(gòu)體定義在Zend/zend.h文件,其結(jié)構(gòu)如下:

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

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;
};

PHP使用這個(gè)結(jié)構(gòu)來(lái)存儲(chǔ)變量的所有數(shù)據(jù)。和其他編譯性靜態(tài)語(yǔ)言不同, PHP在存儲(chǔ)變量時(shí)將PHP用戶空間的變量類型也保存在同一個(gè)結(jié)構(gòu)體中。這樣我們就能通過(guò)這些信息獲取到變量的類型。
zval結(jié)構(gòu)體中有四個(gè)字段,其含義分別為:

屬性名 含義 默認(rèn)值
refcount__gc 表示引用計(jì)數(shù) 1
is_ref__gc 表示是否為引用 0
value 存儲(chǔ)變量的值
type 變量具體的類型

在PHP5.3之后,引入了新的垃圾收集機(jī)制,引用計(jì)數(shù)和引用的字段名改為refcount__gc和is_ref__gc。在此之前為refcount和is__ref。

而變量的值則存儲(chǔ)在另外一個(gè)結(jié)構(gòu)體zvalue_value中。值存儲(chǔ)見(jiàn)下面的介紹。
PHP用戶空間指的在PHP語(yǔ)言這一層面,而本書中大部分地方都在探討PHP的實(shí)現(xiàn)。 這些實(shí)現(xiàn)可以理解為內(nèi)核空間。由于PHP使用C實(shí)現(xiàn),而這個(gè)空間的范疇就會(huì)限制在C語(yǔ)言。 而PHP用戶空間則會(huì)受限于PHP語(yǔ)法及功能提供的范疇之內(nèi)。 例如有些PHP擴(kuò)展會(huì)提供一些PHP函數(shù)或者類,這就是向PHP用戶空間導(dǎo)出了方法或類。
變量類型
zval結(jié)構(gòu)體的type字段就是實(shí)現(xiàn)弱類型最關(guān)鍵的字段了,type的值可以為: IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_ARRAY、IS_OBJECT和IS_RESOURCE 之一。 從字面上就很好理解,他們只是類型的唯一標(biāo)示,根據(jù)類型的不同將不同的值存儲(chǔ)到value字段。 除此之外,和他們定義在一起的類型還有IS_CONSTANT和IS_CONSTANT_ARRAY。
這和我們?cè)O(shè)計(jì)數(shù)據(jù)庫(kù)時(shí)的做法類似,為了避免重復(fù)設(shè)計(jì)類似的表,使用一個(gè)標(biāo)示字段來(lái)記錄不同類型的數(shù)據(jù)。

變量的值存儲(chǔ)
前面提到變量的值存儲(chǔ)在zvalue_value聯(lián)合體中,結(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;

這里使用聯(lián)合體而不是用結(jié)構(gòu)體是出于空間利用率的考慮,因?yàn)橐粋€(gè)變量同時(shí)只能屬于一種類型。 如果使用結(jié)構(gòu)體的話將會(huì)不必要的浪費(fèi)空間,而PHP中的所有邏輯都圍繞變量來(lái)進(jìn)行的,這樣的話, 內(nèi)存浪費(fèi)將是十分大的。這種做法成本小但收益非常大。
各種類型的數(shù)據(jù)會(huì)使用不同的方法來(lái)進(jìn)行變量值的存儲(chǔ),其對(duì)應(yīng)賦值方式如下:

1. 一般類型

變量類型 ?
boolean ZVAL_BOOL 布爾型/整型的變量值存儲(chǔ)于(zval).value.lval中,其類型也會(huì)以相應(yīng)的IS_*進(jìn)行存儲(chǔ)。
Z_TYPE_P(z)=IS_BOOL/LONG; Z_LVAL_P(z)=((b)!=0);
integer ZVAL_LONG
float ZVAL_DOUBLE
null ZVAL_NULL NULL值的變量值不需要存儲(chǔ),只需要把(zval).type標(biāo)為IS_NULL。
Z_TYPE_P(z)=IS_NULL;
resource ZVAL_RESOURCE 資源類型的存儲(chǔ)與其他一般變量無(wú)異,但其初始化及存取實(shí)現(xiàn)則不同。
Z_TYPE_P(z) = IS_RESOURCE; Z_LVAL_P(z) = l;

2. 字符串Sting
字符串的類型標(biāo)示和其他數(shù)據(jù)類型一樣,不過(guò)在存儲(chǔ)字符串時(shí)多了一個(gè)字符串長(zhǎng)度的字段。

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

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

C中字符串是以\0結(jié)尾的字符數(shù)組,這里多存儲(chǔ)了字符串的長(zhǎng)度,這和我們?cè)谠O(shè)計(jì)數(shù)據(jù)庫(kù)時(shí)增加的冗余字段異曲同工。 因?yàn)橐獙?shí)時(shí)獲取到字符串的長(zhǎng)度的時(shí)間復(fù)雜度是O(n),而字符串的操作在PHP中是非常頻繁的,這樣能避免重復(fù)計(jì)算字符串的長(zhǎng)度, 這能節(jié)省大量的時(shí)間,是空間換時(shí)間的做法。 這么看在PHP中strlen()函數(shù)可以在常數(shù)時(shí)間內(nèi)獲取到字符串的長(zhǎng)度。 計(jì)算機(jī)語(yǔ)言中字符串的操作都非常之多,所以大部分高級(jí)語(yǔ)言中都會(huì)存儲(chǔ)字符串的長(zhǎng)度。

3. 數(shù)組Array

數(shù)組是PHP中最常用,也是最強(qiáng)大變量類型,它可以存儲(chǔ)其他類型的數(shù)據(jù),而且提供各種內(nèi)置操作函數(shù)。數(shù)組的存儲(chǔ)相對(duì)于其他變量要復(fù)雜一些, 數(shù)組的值存儲(chǔ)在zvalue_value.ht字段中,它是一個(gè)HashTable類型的數(shù)據(jù)。 PHP的數(shù)組使用哈希表來(lái)存儲(chǔ)關(guān)聯(lián)數(shù)據(jù)。哈希表是一種高效的鍵值對(duì)存儲(chǔ)結(jié)構(gòu)。PHP的哈希表實(shí)現(xiàn)中使用了兩個(gè)數(shù)據(jù)結(jié)構(gòu)HashTable和Bucket。 PHP所有的工作都由哈希表實(shí)現(xiàn),在下節(jié)HashTable中將進(jìn)行哈希表基本概念的介紹以及PHP的哈希表實(shí)現(xiàn)。

4. 對(duì)象Object

在面向?qū)ο笳Z(yǔ)言中,我們能自己定義自己需要的數(shù)據(jù)類型,包括類的屬性,方法等數(shù)據(jù)。而對(duì)象則是類的一個(gè)具體實(shí)現(xiàn)。 對(duì)象有自身的狀態(tài)和所能完成的操作。
PHP的對(duì)象是一種復(fù)合型的數(shù)據(jù),使用一種zend_object_value的結(jié)構(gòu)體來(lái)存放。其定義如下:

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

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

PHP的對(duì)象只有在運(yùn)行時(shí)才會(huì)被創(chuàng)建,前面的章節(jié)介紹了EG宏,這是一個(gè)全局結(jié)構(gòu)體用于保存在運(yùn)行時(shí)的數(shù)據(jù)。 其中就包括了用來(lái)保存所有被創(chuàng)建的對(duì)象的對(duì)象池,EG(objects_store),而object對(duì)象值內(nèi)容的zend_object_handle域就是當(dāng)前 對(duì)象在對(duì)象池中所在的索引,handlers字段則是將對(duì)象進(jìn)行操作時(shí)的處理函數(shù)保存起來(lái)。 這個(gè)結(jié)構(gòu)體及對(duì)象相關(guān)的類的結(jié)構(gòu)_zend_class_entry,后面會(huì)介紹到。
PHP的弱變量容器的實(shí)現(xiàn)方式是兼容并包的形式體現(xiàn),針對(duì)每種類型的變量都有其對(duì)應(yīng)的標(biāo)記和存儲(chǔ)空間。 使用強(qiáng)類型的語(yǔ)言在效率上通常會(huì)比弱類型高,因?yàn)楹芏嘈畔⒛茉谶\(yùn)行之前就能確定,這也能幫助排除程序錯(cuò)誤。 而這帶來(lái)的問(wèn)題是編寫代碼相對(duì)會(huì)受制約。

PHP主要的用途是作為Web開(kāi)發(fā)語(yǔ)言,在普通的Web應(yīng)用中瓶頸通常在業(yè)務(wù)和數(shù)據(jù)訪問(wèn)這一層。不過(guò)在大型應(yīng)用下語(yǔ)言也會(huì)是一個(gè)關(guān)鍵因素。 facebook因此就使用了自己的php實(shí)現(xiàn)。將PHP編譯為C++代碼來(lái)提高性能。不過(guò)facebook的hiphop并不是完整的php實(shí)現(xiàn), 由于它是直接將php編譯為C++,有一些PHP的動(dòng)態(tài)特性比如eval結(jié)構(gòu)就無(wú)法實(shí)現(xiàn)。當(dāng)然非要實(shí)現(xiàn)也是有方法的, hiphop不實(shí)現(xiàn)應(yīng)該也是做了一個(gè)權(quán)衡。

相關(guān)文章

  • php接口隔離原則實(shí)例分析

    php接口隔離原則實(shí)例分析

    這篇文章主要介紹了php接口隔離原則,結(jié)合實(shí)例形式分析了PHP接口隔離原則的相關(guān)原理、使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-11-11
  • PHP加密解密類實(shí)例分析

    PHP加密解密類實(shí)例分析

    這篇文章主要介紹了PHP加密解密類,實(shí)例分析了php實(shí)現(xiàn)加密與解密的原理與相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • 利用php+mcDropdown實(shí)現(xiàn)文件路徑可在下拉框選擇

    利用php+mcDropdown實(shí)現(xiàn)文件路徑可在下拉框選擇

    以下是對(duì)php+mcDropdown實(shí)現(xiàn)文件路徑可在下拉框進(jìn)行選擇的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-08-08
  • PHP使用strtotime獲取上個(gè)月、下個(gè)月、本月的日期

    PHP使用strtotime獲取上個(gè)月、下個(gè)月、本月的日期

    在PHP中有個(gè)叫做strtotime的函數(shù)。strtotime 實(shí)現(xiàn)功能:獲取某個(gè)日期的時(shí)間戳,或獲取某個(gè)時(shí)間的時(shí)間戳。strtotime 將任何英文文本的日期時(shí)間描述解析為Unix時(shí)間戳
    2015-12-12
  • 解析PHP對(duì)現(xiàn)有搜索引擎的調(diào)用

    解析PHP對(duì)現(xiàn)有搜索引擎的調(diào)用

    本篇文章是關(guān)于PHP對(duì)現(xiàn)有搜索引擎的調(diào)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • 解析php5配置使用pdo

    解析php5配置使用pdo

    本篇文章是對(duì)php5配置使用pdo的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • PHP添加X(jué)debug擴(kuò)展的方法

    PHP添加X(jué)debug擴(kuò)展的方法

    xdegug是一個(gè)很好的php調(diào)試擴(kuò)展,安裝方法也很簡(jiǎn)單,基本和其他的擴(kuò)展安裝方式差不多
    2014-02-02
  • 用PHP書寫安全的腳本代碼

    用PHP書寫安全的腳本代碼

    在很長(zhǎng)一段時(shí)間內(nèi),PHP作為服務(wù)器端腳本語(yǔ)言的最大賣點(diǎn)之一就是會(huì)為從表單提交的值自動(dòng)建立一個(gè)全局變量。在PHP 4.1中,PHP的制作者們推薦了一個(gè)訪問(wèn)提交數(shù)據(jù)的替代手段
    2012-02-02
  • 淺析Mysql 數(shù)據(jù)回滾錯(cuò)誤的解決方法

    淺析Mysql 數(shù)據(jù)回滾錯(cuò)誤的解決方法

    以下小編為大家介紹一下關(guān)于Mysql數(shù)據(jù)回滾錯(cuò)誤的解決方法。需要的朋友可以過(guò)來(lái)參考下
    2013-08-08
  • rephactor 優(yōu)秀的PHP的重構(gòu)工具

    rephactor 優(yōu)秀的PHP的重構(gòu)工具

    從PHP5開(kāi)始,提供了強(qiáng)大的面向?qū)ο蠊δ?。使得PHP能夠完全按設(shè)計(jì)模式編程。
    2011-06-06

最新評(píng)論