目錄
變數的基礎結構
zval的實作
#PHP5 與PHP7 的zval 結構對比
此外,在 PHP5 中,所有的變數都在堆中申請,但是對於臨時變數來說,沒有必要在堆中申請。所以在 PHP7 中對此做了最佳化,臨時變數是直接在堆疊中申請的。
首頁 後端開發 PHP7 掌握 PHP7 的基本變數

掌握 PHP7 的基本變數

Nov 17, 2020 pm 04:40 PM
php7

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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

php7檢測tcp埠不好用怎麼解決 php7檢測tcp埠不好用怎麼解決 Mar 22, 2023 am 09:30 AM

php7檢測tcp埠不好用怎麼解決

php7.0怎麼安裝mongo擴展 php7.0怎麼安裝mongo擴展 Nov 21, 2022 am 10:25 AM

php7.0怎麼安裝mongo擴展

php7.0安裝了插件還是顯示未安裝怎麼辦 php7.0安裝了插件還是顯示未安裝怎麼辦 Apr 02, 2024 pm 07:39 PM

php7.0安裝了插件還是顯示未安裝怎麼辦

php8和php7哪個好 php8和php7哪個好 Nov 16, 2023 pm 03:09 PM

php8和php7哪個好

PHP 伺服器環境常見問題指南:快速解決常見難題 PHP 伺服器環境常見問題指南:快速解決常見難題 Apr 09, 2024 pm 01:33 PM

PHP 伺服器環境常見問題指南:快速解決常見難題

php7.0怎麼安裝部署 php7.0怎麼安裝部署 Nov 30, 2022 am 09:56 AM

php7.0怎麼安裝部署

php7怎麼下載與安裝(教學分享) php7怎麼下載與安裝(教學分享) Mar 23, 2023 pm 02:11 PM

php7怎麼下載與安裝(教學分享)

php7和php5語法有什麼差別 php7和php5語法有什麼差別 Jul 10, 2023 pm 03:25 PM

php7和php5語法有什麼差別

See all articles