我們都知道php是乙個弱型別語言,它的變數理論上可以儲存任何型別的資料。
那麼,php的變數在核心中究竟是怎麼實現的呢?
在php核心中,變數稱為zval,變數的值稱為zend_value,注意這是兩個不同的東西。
php中變數的記憶體是通過引用計數的方式進行管理的,在php7之前,zval容器中有兩個位元組的額外資訊,乙個是"is_ref",是個bool值,用來標識這個變數是否是屬於引用集合(reference set)。通過這個位元組,php引擎才能把普通變數和引用變數區分開來。另乙個是"refcount",用以標識指向這個zval變數容器的變數個數。
zend.h中的定義如下(php7之前的版本):
struct _zval_struct ;
而php7發布之後把這引用計數資訊放到了zend_value中,其變數之間的傳遞和賦值一般也是針對zend_value。
我們下面的討論如無特殊說明,都是基於php7。
php7之後zval變化較大,我們先來看變數基礎結構的定義
typedef struct _zval_struct zval;
typedef union _zend_value ww;
} zend_value;
struct _zval_struct v;
uint32_t type_info; //上面4個值的組合值,可以直接根據type_info取到4個對應位置的值
} u1;
union u2; //一些輔助值
};
和php7之前版本一樣,zval直接內嵌乙個zend_value用以儲存具體變數型別對應的值或者指標,但是注意zend_value的定義php7和之前版本是不一樣的。
我們可以看到zval中還有兩個union u1和u2
u1中u1.v.type可以用來區分變數的型別,u1.v.type_flags是型別掩碼,在變數的記憶體管理、gc機制中會用到。
u2是個輔助值,假如zval只有value、u1兩個值,整個zval的大小也會對齊到16byte,既然不管有沒有u2大小都是16byte,把多餘的4byte拿出來用於一些特殊用途還是很划算的,比如next在雜湊表解決雜湊衝突時會用到,還有fe_pos在foreach會用到。
注意因為c 語言聯合體的特徵是一次只有乙個成員是有效的並且分配的記憶體與需要記憶體最多的成員匹配(也要考慮記憶體對齊)。所以在zend_value中,只有zend_long和double是直接儲存值的,而其他型別都是指向具體資料結構的指標。這可以避免在宣告變數而未賦值時,造成過多的記憶體消耗
zval.u1.v.type對應的type型別如下:
/* regular data types */
#define is_undef 0
#define is_null 1
#define is_false 2
#define is_true 3
#define is_long 4
#define is_double 5
#define is_string 6
#define is_array 7
#define is_object 8
#define is_resource 9
#define is_reference 10
/* constant expressions */
#define is_constant 11
#define is_constant_ast 12
/* fake types */
#define _is_bool 13
#define is_callable 14
/* internal types */
#define is_indirect 15
#define is_ptr 17
注意其中的標量型別true、false、long、double、null,他們當中true、false、null沒有value,直接根據type區分,而long、double的值則直接存在value中:zend_long、double,也就是標量型別不需要額外的value指標。
php核心中的變數
php是弱型別語言,它可以儲存任何的資料型別。但是php是使用c語言編寫的,而c語言是強型別語言。每個變數都有固定的型別,不能隨意改變變數的型別。在zend zend.h中,檢視結構體 zval結構體就是通常用到的php變數在核心總的表示形式,在zval結構體中,可以看到四個成員變數,分別是 zva...
PHP變數在zend核心中的儲存方式
php中的變數可以儲存任何的資料型別,這是因為它是弱型別語言。但php是用c語言編寫的,c語言是強型別語言,每個變數都有固定的型別,不能隨意改變變數的型別 可以通過強制型別轉變,不過有可能出現問題 在zend引擎中是怎樣可以做到乙個變數儲存任何型別的呢?在zend zend.h標頭檔案中,會發現下面...
PHP核心中的HashTable
本文和大家分享的主要是php核心的hashtable相關使用,希望通過本文的分享,對大家學習php有所幫助。typedef struct bucket bucket typedef struct hashtable hashtable 這個是乙個簡化過的雜湊表結構 bucket是乙個鍊錶,而 has...