首頁 >後端開發 >PHP7 >掌握 PHP7 的基本變數

掌握 PHP7 的基本變數

coldplay.xixi
coldplay.xixi轉載
2020-11-17 16:40:542535瀏覽

PHP7欄位介紹相關基本變數。

掌握 PHP7 的基本變數

變數的基礎結構

我們都知道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 組成

  • u1

u1的作用是用來保存變數類型及其訊息,其裡面的字段用處如下:

type:記錄變數型別。 即可透過 u2.v.type 來存取到

type_flags:對應變數特有類型的標記(如常數類型,需引用計數類型,不可變類型),不同類型的變數對應的 flag 不一樣。

const_flags:常數類型的標記

reserved:保留欄位

  • u2

u2 主要是輔助作用,由於結構體的記憶體對齊,所以u2 的的這塊空間有或沒有u2 都是已經佔據空間了,所以就利用起來。 u2的輔助字段裡面記錄了很多類型信息,這些信息對內部功能有很大的好處,或提升緩存友好性或減少了內存尋址的操作。這裡介紹其中部分欄位。

next:用來解決雜湊衝突問題(雜湊衝突這個目前還不明白),記錄衝突的下一個元素位置。

cache_slot:運行時快取。執行函數時會優先到快取中查找,若快取中沒有,再去全域的 function 表中查找。

num_args:函數呼叫時傳入參數的個數

access_flags:物件類別的存取標識,如public protected private 這些。

  • zend_value
typedef 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 變數在宣告的時候不用顯示的指定其類型,因為不管你賦給變數什麼類型的值,它都能幫你找到對應的儲存結構。

以值為字串的變數為例,其結構是這樣的:

掌握 PHP7 的基本變數

#PHP5 與PHP7 的zval 結構對比

  • PHP5
掌握 PHP7 的基本變數
  • PHP7
掌握 PHP7 的基本變數

##PHP7

可以看到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 的基本變數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除