PHP7欄目介紹相關(guān)基本變量。

我們都知道PHP的變量是弱類型的,聲明的時(shí)候無需指定類型。那么這里面具體是怎么實(shí)現(xiàn)的呢?這就得從變量的基礎(chǔ)結(jié)構(gòu)說起了。
zval的實(shí)現(xiàn)在源碼文件 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;
}復(fù)制代碼zval 的結(jié)構(gòu)由一個(gè)保存變量類型的值或指針的 union 聯(lián)合體 zend_value 以及兩個(gè) union 聯(lián)合體 u1 和 u2 組成
u1u1的作用是用來保存變量類型及其信息,其里面的字段用處如下:
type:記錄變量類型。 即可通過 u2.v.type 來訪問到
type_flags:對應(yīng)變量特有類型的標(biāo)記(如常量類型,需引用計(jì)數(shù)類型,不可變類型),不同類型的變量對應(yīng)的 flag 不一樣。
const_flags:常量類型的標(biāo)記
reserved:保留字段
u2u2 主要是輔助作用,由于結(jié)構(gòu)體的內(nèi)存對齊,所以 u2 的的這塊空間有或者沒有 u2 都是已經(jīng)占據(jù)空間了,所以就利用起來。u2的輔助字段里面記錄了很多類型信息,這些信息對內(nèi)部功能有很大的好處,或提升緩存友好性或減少了內(nèi)存尋址的操作。這里介紹其中部分字段。
next:用來解決哈希沖突問題(哈希沖突這個(gè)目前還不懂),記錄沖突的下一個(gè)元素位置。
cache_slot:運(yùn)行時(shí)緩存。在執(zhí)行函數(shù)時(shí)會(huì)優(yōu)先去緩存中查找,若緩存中沒有,再去全局的 function 表中查找。
num_args:函數(shù)調(diào)用時(shí)傳入?yún)?shù)的個(gè)數(shù)
access_flags:對象類的訪問標(biāo)識(shí),如public protected private 這些。
zend_valuetypedef union _zend_value {
zend_long lval; /* 整型*/
double dval; /* 浮點(diǎn)型 */
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;復(fù)制代碼從 zend__value 中可以看出,long、double 類型直接存儲(chǔ)值,而其它類型都為指針,指向各自的結(jié)構(gòu)。所以,由于 zval 這樣的結(jié)構(gòu),PHP 變量在聲明的時(shí)候不用顯示的指定其類型,因?yàn)椴还苣阗x給變量什么類型的值,它都能幫你找到對應(yīng)的存儲(chǔ)結(jié)構(gòu)。
以值為字符串的變量為例,其結(jié)構(gòu)是這樣的:
可以看到 php7 的 zval 總的只占 16 個(gè)字節(jié),相比 PHP5 的 zval 所占用的 48 個(gè)字節(jié)節(jié)省了很大的內(nèi)存。
此外,在 PHP5 中,所有的變量都在堆中申請,但是對于臨時(shí)變量來說,沒有必要在堆中申請。所以在 PHP7 中對此做了優(yōu)化,臨時(shí)變量是直接在棧中申請的。
常見變量類型下面介紹幾個(gè)常見類型的變量結(jié)構(gòu),其他更多的類型,可自行查看源碼。
整型和浮點(diǎn)型對于整型和浮點(diǎn)型,由于其占用空間小,在 zval 中是直接存儲(chǔ)的 整型的值是存在 lval 里,浮點(diǎn)型值則是存儲(chǔ)在 dval 里。
typedef union _zend_value {
zend_long lval; /* 整型*/
double dval; /* 浮點(diǎn)型 */
...
}復(fù)制代碼字符串PHP 7 中定義了新的字符串結(jié)構(gòu)體。結(jié)構(gòu)如下:
struct _zend_string {
zend_refcounted_h ;
zend_ulong h; /* hash value */
size_t len; char val[1];
};復(fù)制代碼上面各個(gè)字段的意思:
gc: 變量引用信息,所有用到引用計(jì)數(shù)的變量類型都會(huì)有這個(gè)結(jié)構(gòu)。
h: 哈希值,數(shù)組中計(jì)算索引時(shí)會(huì)用到。(據(jù)說這個(gè)操作為 PHP7 提高了 5% 的性能)
len: 字符串長度,通過這個(gè)值保證二進(jìn)制安全
val: 字符串內(nèi)容,變長struct,分配時(shí)按len長度申請內(nèi)存 數(shù)組
array 是 PHP 中非常強(qiáng)大的一個(gè)數(shù)據(jù)結(jié)構(gòu),它的底層實(shí)現(xiàn)就是普通的有序HashTable,這里簡單看下它的結(jié)構(gòu)。后續(xù)再具體深入。
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;
}復(fù)制代碼###對象
PHP7 的對象結(jié)構(gòu)也是重新設(shè)計(jì)了,和 PHP5 的實(shí)現(xiàn)有了很大的不同。
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];
};復(fù)制代碼這里介紹下其中幾個(gè)字段:
gc:gc頭部
*ce:對象對應(yīng)的 class 類
*properties :HashTable結(jié)構(gòu),key 為對象的屬性名,value 是屬性值在properties_tables數(shù)組中的偏移量,通過偏移量在 properties_talbe 找到對應(yīng)的屬性值。
properties_talbe[1]:存儲(chǔ)對象的屬性值
免費(fèi)推薦:PHP7
網(wǎng)頁題目:掌握PHP7的基本變量
文章出自:http://www.chinadenli.net/article28/chspjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、網(wǎng)站設(shè)計(jì)、電子商務(wù)、網(wǎng)站改版、云服務(wù)器、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)