跟廠長學PHP7核心(七):常見變數型別的基本結構
上篇文章講述了變數的儲存結構zval,今天我們就來學習一下幾個常見變數型別的基本結構。
一、型別一覽
zval中的u1.v.type用來儲存變數的型別,而zval.value儲存的是不同型別對應的值,所以type決定value取值的地方,以下是PHP7所定義的所有型別。
#define IS_UNDEF0/* 標記未使用型別 */ #define IS_NULL1/* NULL */ #define IS_FALSE2/* 布林型別false */ #define IS_TRUE3/* 布林型別true */ #define IS_LONG4/* 長整型 */ #define IS_DOUBLE5/* 浮點型 */ #define IS_STRING6/* 字串 */ #define IS_ARRAY7/* 陣列 */ #define IS_OBJECT8/* 物件 */ #define IS_RESOURCE9/* 資源 */ #define IS_REFERENCE10/* 引用 */ /* 常量相關型別 */ #define IS_CONSTANT11/* 常量 */ #define IS_CONSTANT_AST 12/* 常量抽象語法樹 */ /* 偽型別 */ #define _IS_BOOL13 #define IS_CALLABLE14 /* 內部型別 */ #define IS_INDIRECT15/* 間接型別 */ #define IS_PTR17/* 指標型別 */
&
二、不同型別的結構
剛才聊到zval.u1.v.type決定了zval.value,下面來看一下zend_value結構體的定義。
typedef union _zend_value { zend_longlval;/* 整型 */ doubledval;/* 浮點型 */ zend_refcounted*counted;/* 引用計數 */ zend_string*str;/* 字串 */ zend_array*arr;/* 陣列 */ zend_object*obj;/* 物件 */ zend_resource*res;/* 資源 */ zend_reference*ref;/* 引用 */ zend_ast_ref*ast;/* 抽象語法樹 */ zval*zv;/* zval型別 */ void*ptr;/* 指標型別 */ zend_class_entry *ce;/* class型別 */ zend_function*func;/* function型別 */ struct { uint32_t w1; uint32_t w2; } ww; } zend_value;
基本可以看出該結構體的變數和上文定義的型別是一一對應的,我們抽取幾個常用的型別講述一下。
2.1、字串
字串str
對應的結構體是zend_string,它有四個成員,定義如下。
struct _zend_string { zend_refcounted_h gc; zend_ulongh;/* hash value */ size_tlen; charval[1]; };
malloc(sizeof(zend_string)+字串你長度)
2.2、陣列
成員變數arr對應的結構體是zend_array,它就是你可能有所耳聞的HashTable,zend_array結構體定義如下。
struct _zend_array { zend_refcounted_h gc; union { struct { ZEND_ENDIAN_LOHI_4( zend_ucharflags, zend_ucharnApplyCount, zend_ucharnIteratorsCount, zend_ucharreserve) } v; uint32_t flags; } u; uint32_tnTableMask; Bucket*arData; uint32_tnNumUsed; uint32_tnNumOfElements; uint32_tnTableSize; uint32_tnInternalPointer; zend_longnNextFreeElement; dtor_func_tpDestructor; };
$a[] = 1
2.3、物件
struct _zend_object { zend_refcounted_h gc; uint32_thandle; zend_class_entry *ce; const zend_object_handlers *handlers; HashTable*properties; zvalproperties_table[1]; };
- gc:引用計數。
- handle:一次請求期間物件的編號,每一個物件都有一個唯一的編號,與建立的先後順序有關,主要是在垃圾回收的時候使用。
- ce:該物件所屬的類。
- handlers:物件操作的處理函式,比如成員屬性的讀寫、成員方法的獲取、物件的銷燬克隆等。
- properties:普通成員屬性的雜湊表,初始化物件時該值為NULL。
- properties_table:用來儲存普通成員的屬性值,物件對非靜態成員屬性的操作就是通過這個陣列。
參考文獻
- 《PHP7核心剖析》
- 《PHP7底層設計與原始碼實現》