PHP カーネルの深い理解 (5) 変数とデータ型 - 変数の構造と型
元のリンク: http://www.orlion.ga/238/
型プログラミング言語は強い型と弱い型の2種類に分けられます。PHPは弱い型付け言語ですが、C言語は強い型付け言語です。公式の PHP 実装では、すべての変数が同じデータ構造 (zval) を使用して保存されます。この構造には、変数の値だけでなく、変数の型も含まれます。これは PHP の弱い型付けの中核です。
zval 構造体は弱い型付けをどのように実装しますか?
1. PHP 変数の型とストレージ構造
PHP は変数の宣言や使用時にデータ型を指定する必要はありませんが、PHP には型があり、PHP には 8 種類のデータ型があります。スカラー型: ブール、整数、浮動小数点 (倍精度) 文字列; 複合型: 配列、オブジェクト; 特殊型: リソース、NULL
C 言語は PHP Woolen クロスでどのように弱い型を実装しますか?
1. 変数の格納構造
変数の値は、以下に示すように zval 構造体に格納されます。 zval 構造体は Zend/zend.h ファイルで定義されており、その構造は次のとおりです:
typedef struct _zval_struct zval;...struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uint refcount__gc; zend_uchar type; /* active type */ zend_uchar is_ref__gc;};
zval 構造体には 4 つのフィールドがあり、それらの意味は次のとおりです:
属性名 | 含义 | 默认值 |
refcount_gc | 表示引用计数 | 1 |
is_ref_gc | 表示是否为引用 | 0 |
value | 存储变量的值 | |
type | 变量具体的类型 |
PHP5 では、新しいガベージ コレクション メカニズムが導入されました。それ以前は、refcount と is_ref でした。
変数は別の構造体 zvalue_value に格納され、その値は以下の概要を参照してください。
2. 変数の型
zval 構造体の type フィールドは、弱い型指定を実装するための最も重要なフィールドです。 IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_OBJECT、IS_RESOURCE のいずれかになります。さらに、それらで定義されるタイプには、IS_CONSTANT および IS_CONSTANT_ARRAY が含まれます。
2. 変数値の格納
前述したように、値はzvalue_value 共用体では、構造体は次のように定義されます。
typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj;} zvalue_value;
さまざまなタイプのデータは、変数値と対応する割り当てを格納するために異なるメソッドを使用します。メソッドは次のとおりです。
一般的なタイプ:
変数の種類 | マクロ | tr> | |||||||||||||||||
ブール値 | ZVAL_BOOL |
| tr>|||||||||||||||||
整数 | ZVAL_LONG | tr>||||||||||||||||||
float | ZVAL_DOUBLE | Z_TYPE_P(z )=IS_BOOL/LONG;Z_LVAL_P(z)=(b)!=0; | |||||||||||||||||
null | ZVAL_NULL | <🎜>NULL 値の変数値を格納する必要はありません(zval).type を IS_NUL<🎜><🎜>Z_TYPE_P(z)=IS_NULL;<🎜> | |||||||||||||||||
としてマークするだけです。 resource | ZVAL_RESOURCE | <🎜>リソース タイプのストレージは、他の一般的なリソース タイプと変わりません。変数ですが、初期化とストレージの実装が異なります< 🎜><🎜>Z_TYPE_P(z) = IS_RESOURCE = 1;<🎜> |
字符串
字符串的类型标示和其他数据类型一样,不过在存储字符串时多了一个字符串长度的字段。
struct { char *val; int len;} str;
(存储字符串长度是因为字符串的操作十分频繁,有利于节省时间,是空间换时间的做法)
数组Array
数组是PHP中最常用也是最强大变量类型。数组的值存储在zvalue_value.ht字段中,它是一个HashTable类型的数据。PHP数组使用哈希表来存储关联数据。PHP的哈希表实现中使用了两个数据结构HashTable和Bucket。PHP所有的工作都是由哈希表实现。
对象Object
PHP的对象是一种复合型的数据,使用一种zend_object_value的结构体来存放,其定义如下
typedef struct _zend_object_value { zend_object_handle handle; // unsigned int?类型,EG(objects_store).object_buckets的索引 zend_object_handlers *handlers;} zend_object_value;
PHP的对象只有在运行时才会被创建,前面介绍了EG宏,这是一个全局结构体由于保存在运行时的数据。其中就包括了用来保存所有被创建的对象的对象池,EG(objects_store),而object对象值内容的zend_object_handle域就是当前对象在对象池中所在的索引,handlers字段则是将对象进行操作时的处理函数保存起来。
PHP的弱变量容器的实现方式是兼容并包的形式体现。