PHP變數的組成及類型

來源:互聯網
上載者:User
本篇文章主要介紹PHP變數的組成及類型,感興趣的朋友參考下,希望對大家有所協助。

php變數組成部分:

變數名:php語言的變數名以$開頭+英文/底線,可以包含數字、底線、字母,區分大小寫。同時PHP也支援複合變數,形如$$A,增加了php的動態性。

類型:php屬於弱類型語言,可以賦值任意類型的值。

內容:在同一時刻只能有一種值。

php語言中存在8中資料類型,分為三大類:

1. 標量類型:Boolean,integer,float,string;

2. 複合類型:object,array;

3. 特殊類型:NULL,resource;

php作為一種弱類型語言,在實現內部所有變數是通過結構zval來儲存資料的,不僅包含變數的值,也包含變數的類型,是php弱類型的核心。

zval資料結構:

struct _zval_struct{  zvalue_value value;    //儲存變數的值  zend_unint  refcount_gc; //引用計數  zend_char  is_ref_gc;  // 是否為引用  zend_char  type;     //儲存變數的類型}

其中zvalue_value並不是一個結構體,為了節省記憶體使用量的union來實現的,因為在同一時刻變數只能表示一種類型。其原型:

typedef union _zvalue_value{  long lval;           double dval;  struct {      char *val;      int len;      //字串的長度    }str;  HashTable *ht;       //儲存數組  zend_object_value obj;   //對象}zvalue_value;

雜湊表:

php內部很多實現基於雜湊表:變數的範圍、函數表、類的屬性、方法等,Zend引擎內部的很多資料都是儲存在雜湊表中的。

php數組使用雜湊表來儲存關聯資料,雜湊表實現使用兩個資料結構HashTable和Bucket:

HashTable:

typedef struct _hashtable {   uint nTableSize;    // hash Bucket的大小,最小為8,以2x增長。  uint nTableMask;    // nTableSize-1 , 索引取值的最佳化  uint nNumOfElements;  // hash Bucket中當前存在的元素個數,count()函數會直接返回此值   ulong nNextFreeElement; // 下一個數字索引的位置  Bucket *pInternalPointer;  // 當前遍曆的指標(foreach比for快的原因之一)  Bucket *pListHead;     // 儲存數組頭元素指標  Bucket *pListTail;     // 儲存數組尾元素指標  Bucket **arBuckets;     // 儲存hash數組  dtor_func_t pDestructor;  // 在刪除元素時執行的回呼函數,用於資源的釋放  zend_bool persistent;    // 指出了Bucket記憶體配置的方式。如果persisient為TRUE,                  則使用作業系統本身的記憶體配置函數為Bucket分配記憶體,否則使用                  PHP的記憶體配置函數。  unsigned char nApplyCount; // 標記當前hash Bucket被遞迴訪問的次數(防止多次遞迴)  zend_bool bApplyProtection;// 標記當前hash桶允許不允許多次訪問,不允許時,最多隻能遞迴3次#if ZEND_DEBUG  int inconsistent;#endif} HashTable;

在HashTable中容量的擴增,始終調整為接近初始大小的2的整數次方。因為:

在選槽時,這裡使用&操作而不是使用模數,這是因為是相對來說模數操作的消耗和按位與的操作大很多。mask的作用就是將雜湊值對應到槽位所能儲存的索引範圍內。 例如:某個key的索引值是21, 雜湊表的大小為8,則mask為7,則求與時的二進位表示為: 10101 & 111 = 101 也就是十進位的5。 因為2的整數次方-1的二進位比較特殊:後面N位的值都是1,這樣比較容易能將值進行映射, 如果是普通數字進行了二進位與之後會影響雜湊值的結果。那麼雜湊Function Compute的值的平均分布就可能出現影響。

bucket:

typedef struct bucket {  ulong h;      // 對char *key進行hash後的值,或者是使用者指定的數字索引值  uint nKeyLength;  // hash關鍵字的長度,如果數組索引為數字,此值為0  void *pData;    // 指向value,一般是使用者資料的副本,如果是指標資料,則指向pDataPtr  void *pDataPtr;   //如果是指標資料,此值會指向真正的value,同時上面pData會指向此值  struct bucket *pListNext;  // 整個hash表的下一元素  struct bucket *pListLast;  // 整個雜湊表該元素的上一個元素  struct bucket *pNext;    // 存放在同一個hash Bucket內的下一個元素  struct bucket *pLast;    // 同一個雜湊bucket的上一個元素// 儲存當前值所對於的key字串,這個欄位只能定義在最後,實現變長結構體  char arKey[1];       } Bucket;

在Bucket中儲存的是雜湊值而不是雜湊的索引。

上面結構體的最後一個欄位用來儲存key的字串,而這個欄位卻申明為只有一個字元的數組, 其實這裡是一種長見的變長結構體,主要的目的是增加靈活性。 以下為雜湊表插入新元素時申請空間的代碼

p = (Bucket *) pemalloc(sizeof(Bucket) - 1 + nKeyLength, ht->persistent);if (!p) {  return FAILURE;}memcpy(p->arKey, arKey, nKeyLength);

插入過程圖

雜湊演算法

php中hash函數使用DJBX33A演算法來實現。

對象:

php對象使用資料結構zend_object_value來儲存;

總結:以上就是本篇文的全部內容,希望能對大家的學習有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.