PHP7欄目介紹相關基本變量。
成都創新互聯專注為客戶提供全方位的互聯網綜合服務,包含不限于網站建設、成都網站制作、寶塔網絡推廣、成都小程序開發、寶塔網絡營銷、寶塔企業策劃、寶塔品牌公關、搜索引擎seo、人物專訪、企業宣傳片、企業代運營等,從售前售中售后,我們都將竭誠為您服務,您的肯定,是我們大的嘉獎;成都創新互聯為所有大學生創業者提供寶塔建站搭建服務,24小時服務熱線:028-86922220,官方網址:vcdvsql.cn變量的基礎結構我們都知道PHP的變量是弱類型的,聲明的時候無需指定類型。那么這里面具體是怎么實現的呢?這就得從變量的基礎結構說起了。
zval的實現在源碼文件 zend_type.h 中,可以看到 zval 的定義:
typedef struct _zval_struct zval;struct _zval_struct { zend_value value; /* value */ union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar type, /* active type */ zend_uchar type_flags, zend_uchar const_flags, zend_uchar reserved) /* call info for EX(This) */ } v; uint32_t type_info; } u1; union { uint32_t next; /* hash collision chain */ uint32_t cache_slot; /* literal cache slot */ uint32_t lineno; /* line number (for ast nodes) */ uint32_t num_args; /* arguments number for EX(This) */ uint32_t fe_pos; /* foreach position */ uint32_t fe_iter_idx; /* foreach iterator index */ uint32_t access_flags; /* class constant access flags */ uint32_t property_guard; /* single property guard */ uint32_t extra; /* not further specified */ } u2; }復制代碼
zval 的結構由一個保存變量類型的值或指針的 union 聯合體 zend_value 以及兩個 union 聯合體 u1 和 u2 組成
u1u1的作用是用來保存變量類型及其信息,其里面的字段用處如下:
type:記錄變量類型。 即可通過 u2.v.type 來訪問到
type_flags:對應變量特有類型的標記(如常量類型,需引用計數類型,不可變類型),不同類型的變量對應的 flag 不一樣。
const_flags:常量類型的標記
reserved:保留字段
u2u2 主要是輔助作用,由于結構體的內存對齊,所以 u2 的的這塊空間有或者沒有 u2 都是已經占據空間了,所以就利用起來。u2的輔助字段里面記錄了很多類型信息,這些信息對內部功能有很大的好處,或提升緩存友好性或減少了內存尋址的操作。這里介紹其中部分字段。
next:用來解決哈希沖突問題(哈希沖突這個目前還不懂),記錄沖突的下一個元素位置。
cache_slot:運行時緩存。在執行函數時會優先去緩存中查找,若緩存中沒有,再去全局的 function 表中查找。
num_args:函數調用時傳入參數的個數
access_flags:對象類的訪問標識,如public protected private 這些。
zend_valuetypedef union _zend_value { zend_long lval; /* 整型*/ double dval; /* 浮點型 */ zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zend_ast_ref *ast; zval *zv; void *ptr; zend_class_entry *ce; zend_function *func; struct { uint32_t w1; uint32_t w2; } ww; } zend_value;復制代碼
從 zend__value 中可以看出,long、double 類型直接存儲值,而其它類型都為指針,指向各自的結構。所以,由于 zval 這樣的結構,PHP 變量在聲明的時候不用顯示的指定其類型,因為不管你賦給變量什么類型的值,它都能幫你找到對應的存儲結構。
以值為字符串的變量為例,其結構是這樣的:
PHP5 與 PHP7 的 zval 結構對比PHP5PHP7可以看到 php7 的 zval 總的只占 16 個字節,相比 PHP5 的 zval 所占用的 48 個字節節省了很大的內存。
此外,在 PHP5 中,所有的變量都在堆中申請,但是對于臨時變量來說,沒有必要在堆中申請。所以在 PHP7 中對此做了優化,臨時變量是直接在棧中申請的。
常見變量類型下面介紹幾個常見類型的變量結構,其他更多的類型,可自行查看源碼。
整型和浮點型對于整型和浮點型,由于其占用空間小,在 zval 中是直接存儲的 整型的值是存在 lval 里,浮點型值則是存儲在 dval 里。
typedef union _zend_value { zend_long lval; /* 整型*/ double dval; /* 浮點型 */ ... }復制代碼字符串
PHP 7 中定義了新的字符串結構體。結構如下:
struct _zend_string { zend_refcounted_h ; zend_ulong h; /* hash value */ size_t len; char val[1]; };復制代碼
上面各個字段的意思:
gc: 變量引用信息,所有用到引用計數的變量類型都會有這個結構。
h: 哈希值,數組中計算索引時會用到。(據說這個操作為 PHP7 提高了 5% 的性能)
len: 字符串長度,通過這個值保證二進制安全
val: 字符串內容,變長struct,分配時按len長度申請內存 數組
array 是 PHP 中非常強大的一個數據結構,它的底層實現就是普通的有序HashTable,這里簡單看下它的結構。后續再具體深入。
typedef struct _zend_array HashTable;struct _zend_array { zend_refcounted_h gc; union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar flags, zend_uchar nApplyCount, zend_uchar nIteratorsCount, zend_uchar consistency) } v; uint32_t flags; } u; uint32_t nTableMask; Bucket *arData; uint32_t nNumUsed; uint32_t nNumOfElements; uint32_t nTableSize; uint32_t nInternalPointer; zend_long nNextFreeElement; dtor_func_t pDestructor; }復制代碼
###對象
PHP7 的對象結構也是重新設計了,和 PHP5 的實現有了很大的不同。
struct _zend_object { zend_refcounted_h gc; uint32_t handle; zend_class_entry *ce; const zend_object_handlers *handlers; HashTable *properties; zval properties_table[1]; };復制代碼
這里介紹下其中幾個字段:
gc:gc頭部
*ce:對象對應的 class 類
*properties :HashTable結構,key 為對象的屬性名,value 是屬性值在properties_tables數組中的偏移量,通過偏移量在 properties_talbe 找到對應的屬性值。
properties_talbe[1]:存儲對象的屬性值
免費推薦:PHP7
網頁題目:掌握PHP7的基本變量
文章出自:http://vcdvsql.cn/article28/chspjp.html
成都網站建設公司_創新互聯,為您提供靜態網站、網站設計、電子商務、網站改版、云服務器、標簽優化
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯