深入理解PHP核心:變數及資料型別

語言: CN / TW / HK

1、現實生活中我們會找一個小箱子來存放物品,一來顯得不那麼凌亂,二來方便以後找到。計算機也是這個道理,我們需要先在記憶體中找一塊區域,規定用它來存放資料,並起一個好記的名字,方便以後查詢。這塊區域就是“小箱子”,我們可以把資料放進去了。

2、資料型別用來說明資料的型別,確定了資料的解釋方式,同時指明瞭資料的長度,也就是資料佔用的位元組數

3、變數名就是給那塊記憶體區域起了個名字,方便使用

4、.從型別劃分

1)靜態型別語言:比如c/java,型別檢查在編譯器確定

2)動態型別語言: 比如PHP/python,型別在執行時確定

3)無型別語言: 比如組合語言,對型別無知

5、PHP變數型別及儲存結構

PHP在宣告或使用變數的時候,並不需要顯式指明其資料型別。

PHP是弱型別語言,這並不表示PHP沒有型別,在PHP中,存在8種變數型別

標量型別: boolean、integer、float(double)、string

複合型別: array、object

特殊型別: resource、NULL

6、PHP變數儲存結構

變數的值儲存到以下所示zval結構體中

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;

};

1)結構體是一種集合,它裡面包含了多個變數或陣列,它們的型別可以相同,也可以不同,每個這樣的變數或陣列都稱為結構體的成員(Member),使用結構體(Struct)來存放一組不同型別的資料

7、PHP變數型別

zval結構體的type欄位就是實現弱型別最關鍵的欄位了,type的值可以為: IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_ARRAY、IS_OBJECT和IS_RESOURCE 之一。 從字面上就很好理解,他們只是型別的唯一標示,根據型別的不同將不同的值儲存到value欄位。 除此之外,和他們定義在一起的型別還有IS_CONSTANT和IS_CONSTANT_ARRAY。

這和我們設計資料庫時的做法類似,為了避免重複設計類似的表,使用一個標示欄位來記錄不同型別的資料。

8、PHP變數的值儲存

變數的值儲存在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;

結構體和聯合體的區別在於:結構體的各個成員會佔用不同的記憶體,互相之間沒有影響;而聯合體的所有成員佔用同一段記憶體,修改一個成員會影響其餘所有成員。

結構體佔用的記憶體大於等於所有成員佔用的記憶體的總和(成員之間可能會存在縫隙),聯合體佔用的記憶體等於最長的成員佔用的記憶體。聯合體使用了記憶體覆蓋技術,同一時刻只能儲存一個成員的值,如果對新的成員賦值,就會把原來成員的值覆蓋掉。

1)一般型別

巨集定義是預處理命令的一種,它允許用一個識別符號來表示一個字串#define 巨集名 字串

帶引數巨集定義對帶引數的巨集,在呼叫中,不僅要巨集展開,而且要用實參去代換形參。

2)字串String

struct {

    char *val;

    int len;

} str;

C中字串是以\0結尾的字元陣列,這裡多儲存了字串的長度,這和我們在設計資料庫時增加的冗餘欄位異曲同工。 因為要實時獲取到字串的長度的時間複雜度是O(n),而字串的操作在PHP中是非常頻繁的,這樣能避免重複計算字串的長度, 這能節省大量的時間,是空間換時間的做法。

這麼看在PHP中strlen()函式可以在常數時間內獲取到字串的長度。 計算機語言中字串的操作都非常之多,所以大部分高階語言中都會儲存字串的長度。

1.其實在C語言中沒有專門的字串型別,我們只能使用陣列或者指標來間接地儲存字串。

2.字元陣列實際上是一系列字元的集合,也就是字串(String),在C語言中,字串總是以'\0'作為串的結束符。陣列的長度要比字串的長度(字串長度不包括 '\0')大1

3.另外一種表示字串的方法,就是直接使用一個指標指向字串,字串中的所有字元在記憶體中是連續排列的,val指向的是字串的第 0 個字元;我們通常將第 0 個字元的地址稱為字串的首地址。字串中每個字元的型別都是char,所以 str 的型別也必須是char *

PHP的弱變數容器的實現方式是相容幷包的形式體現,針對每種型別的變數都有其對應的標記和儲存空間。 使用強型別的語言在效率上通常會比弱型別高,因為很多資訊能在執行之前就能確定,這也能幫助排除程式錯誤。 而這帶來的問題是編寫程式碼相對會受制約。

以上內容希望幫助到大家,更多PHP大廠PDF面試文件,PHP進階架構視訊資料,PHP精彩好文免費獲取可以關注公眾號:PHP開源社群,或者訪問:

2021金三銀四大廠面試真題集錦,必看!

騰訊一面的Redis秒殺面試題你會麼?

四年精華PHP技術文章整理合集——PHP框架篇

四年精華PHP技術文合集——微服務架構篇

四年精華PHP技術文合集——分散式架構篇

四年精華PHP技術文合集——高併發場景篇

四年精華PHP技術文章整理合集——資料庫篇