元のリンク: http://www.orlion.ga/238/
プログラミング言語の種類は、強い型付けと弱い型付けの2種類に分けられます。PHPは弱い型付け言語ですが、C言語は強い型付け言語です。公式の PHP 実装では、すべての変数が同じデータ構造 (zval) を使用して保存されます。この構造には、変数の値だけでなく、変数の型も含まれます。これは PHP の弱い型付けの中核です。
zval 構造体は弱い型をどのように実装しますか?
1. PHP 変数の型とストレージ構造
変数を宣言して使用する場合、PHP はデータ型を指定する必要はありませんが、PHP には 8 つのデータ型があり、次の 3 つのカテゴリに分類できます。整数、float(double) 文字列; 複合型: 配列、オブジェクト; 特殊な型: リソース、NULL
C 言語は PHP で弱い型付けをどのように実装しますか?
1. 可変ストレージ構造
変数の値は、以下に示すように zval 構造体に格納されます。zval 構造体は Zend/zend.h ファイルで定義されており、その構造は次のとおりです。 リーリー
zval 構造体には 4 つのフィールドがあり、それらの意味は次のとおりです:
意味 | デフォルト値 | |
は参照カウントを意味します | 1 | |
参考かどうかを示します | 0 | |
変数の値を保存する | ||
変数の特定のタイプ |
2. 変数タイプ
zval 構造体の type フィールドは、弱い型指定を実装するための最も重要なフィールドです。 type の値は、IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_OBJECT、IS_RESOURCE のいずれかになります。さらに、それらで定義されるタイプには、IS_CONSTANT および IS_CONSTANT_ARRAY が含まれます。
2. 変数値の保存
前述の変数の値は zvalue_value 共用体に格納され、その構造は次のように定義されます: リーリー
さまざまなタイプのデータは、変数値を格納するために異なるメソッドを使用します。対応する割り当てメソッドは次のとおりです。
一般的なタイプ:
変数型
ブール値 | ||
ブール/整数変数の値は (zval).value.lval に格納され、その型も | になります。 | 対応するIS_*を使用して保存します
整数 |
フロート | ||
Z_TYPE_P(z)=IS_BOOL/LONG;Z_LVAL_P(z)=(b)!=0; | ヌル | |
NULL 値を含む変数値を保存する必要はなく、(zval).type を IS_NUL としてマークするだけです | Z_TYPE_P(z)=IS_NULL; |
リソース |
リソースタイプのストレージは他の一般的な変数と変わりませんが、その初期化とストレージの実装は異なります | Z_TYPE_P(z) = IS_RESOURCE と同じ; |
字符串 字符串的类型标示和其他数据类型一样,不过在存储字符串时多了一个字符串长度的字段。 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的弱变量容器的实现方式是兼容并包的形式体现。 |