この記事では主にPHP変数の構成と種類について紹介します。興味のある方はぜひ参考にしてください。
PHP 変数コンポーネント:
変数名: PHP 言語の変数名は $ + 英語/アンダースコアで始まり、数字、アンダースコア、文字を含めることができ、大文字と小文字が区別されます。同時に、PHP は $$A の形式の複合変数もサポートしており、これにより PHP のダイナミクスが向上します。
型: PHP は弱い型指定言語であり、任意の型の値を割り当てることができます。
内容: 同時に存在できる値は 1 つだけです。
PHP 言語には 8 つのデータ型があり、次の 3 つの主要なカテゴリに分類されます。 1. スカラー型: ブール、整数、浮動小数点数、文字列。 3 . 特別な型: NULL、リソース
弱く型指定された言語として、php は変数の値だけでなく、php の核となる変数の型も含む構造 zval を介して内部的にデータを保存します。タイピングが弱い。
zval データ構造体:
struct _zval_struct{ zvalue_value value; //存储变量的值 zend_unint refcount_gc; //引用计数 zend_char is_ref_gc; // 是否为引用 zend_char type; //存储变量的类型 }
このうち、zvalue_value は、変数が同時に 1 つの型しか表現できないため、メモリを節約するために構造体ではありません。そのプロトタイプ:
typedef union _zvalue_value{ long lval; double dval; struct { char *val; int len; //字符串的长度 }str; HashTable *ht; //保存数组 zend_object_value obj; //对象 }zvalue_value;
PHP 内の多くの実装は、変数スコープ、関数テーブル、クラス属性、メソッドなどのハッシュ テーブルに基づいています。Zend エンジン内の多くのデータは、テーブル内のハッシュに格納されます。
PHP 配列は、ハッシュ テーブルを使用して関連データを格納します。ハッシュ テーブルの実装では、HashTable と Bucket の 2 つのデータ構造が使用されます。
HashTable:typedef struct _hashtable { uint nTableSize; // hash Bucket的大小,最小为8,以2x增长。 uint nTableMask; // nTableSize-1 , 索引取值的优化 uint nNumOfElements; // hash Bucket中当前存在的元素个数,count()函数会直接返回此值 ulong nNextFreeElement; // 下一个数字索引的位置 Bucket *pInternalPointer; // 当前遍历的指针(foreach比for快的原因之一) Bucket *pListHead; // 存储数组头元素指针 Bucket *pListTail; // 存储数组尾元素指针 Bucket **arBuckets; // 存储hash数组 dtor_func_t pDestructor; // 在删除元素时执行的回调函数,用于资源的释放 zend_bool persistent; // 指出了Bucket内存分配的方式。如果persisient为TRUE, 则使用操作系统本身的内存分配函数为Bucket分配内存,否则使用 PHP的内存分配函数。 unsigned char nApplyCount; // 标记当前hash Bucket被递归访问的次数(防止多次递归) zend_bool bApplyProtection;// 标记当前hash桶允许不允许多次访问,不允许时,最多只能递归3次 #if ZEND_DEBUG int inconsistent; #endif } HashTable;
HashTable の容量の拡張は、常に初期サイズに近づくように調整されます。 2 の整数乗。理由:
スロットを選択するとき、モジュロ演算の代わりに & 演算が使用されます。これは、モジュロ演算がビット単位の AND 演算よりも比較的高価であるためです。マスクの機能は、スロットが保存できるインデックス範囲にハッシュ値をマップすることです。 たとえば、特定のキーのインデックス値は 21、ハッシュ テーブルのサイズは 8、マスクは 7、合計の 2 進表現は 10101 & 111 = 101 (10 進数では 5) となります。 2 の整数 -1 乗の 2 進数系は特殊であるため、次の N ビットの値はすべて 1 となり、通常の数値であり 2 進数で結合される場合、値のマッピングが容易になります。 、ハッシュ値の結果に影響します。その場合、ハッシュ関数によって計算された値の平均分布が影響を受ける可能性があります。
bucket:typedef struct bucket { ulong h; // 对char *key进行hash后的值,或者是用户指定的数字索引值 uint nKeyLength; // hash关键字的长度,如果数组索引为数字,此值为0 void *pData; // 指向value,一般是用户数据的副本,如果是指针数据,则指向pDataPtr void *pDataPtr; //如果是指针数据,此值会指向真正的value,同时上面pData会指向此值 struct bucket *pListNext; // 整个hash表的下一元素 struct bucket *pListLast; // 整个哈希表该元素的上一个元素 struct bucket *pNext; // 存放在同一个hash Bucket内的下一个元素 struct bucket *pLast; // 同一个哈希bucket的上一个元素 // 保存当前值所对于的key字符串,这个字段只能定义在最后,实现变长结构体 char arKey[1]; } Bucket;
ハッシュ値は、ハッシュのインデックスの代わりにバケットに保存されます。
上記の構造体の最後のフィールドはキー文字列を保存するために使用されますが、このフィールドは 1 文字だけの配列として宣言されています。実際、これは一般的な可変長構造体であり、その主な目的は柔軟性を高めることです。 。 以下は、ハッシュテーブルに新しい要素を挿入するときにスペースを適用するコードです phpのハッシュ関数は、DJBX33Aアルゴリズムを使用して実装されています。 オブジェクト: PHP オブジェクトはデータ構造 zend_object_value; を使用して保存されます。 概要: 上記がこの記事の全内容です。皆さんの学習に役立つことを願っています。 関連する推奨事項: 以上がPHP変数の構成と型の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。p = (Bucket *) pemalloc(sizeof(Bucket) - 1 + nKeyLength, ht->persistent);
if (!p) {
return FAILURE;
}
memcpy(p->arKey, arKey, nKeyLength);