の内部構造を理解する必要があるのか1. HASHTable
の定義1. ? ?ハッシュテーブルは、指定されたハッシュ関数HASHに従って、キー名keyをテーブル内のレコードにマッピングします。この配列がハッシュテーブルです。ここでの HASH は、MD5、CRC32、SHA1、カスタム関数などの関数を指します。
2. ハッシュテーブルの性能? HashTable は非常に検索性能の高いデータ構造であり、多くの言語で実装されています。理想的には、HashTable のパフォーマンスは O(1) です。パフォーマンスの消費は主に、HASH(key) を通じてテーブル内のレコードを直接検索するハッシュ関数 HASH(key) に集中します。実際には、key1!=key2 が発生することがよくありますが、HASH(key1)=HASH(key2) という状況が発生する可能性が低いほど、HashTable のパフォーマンスは向上します。もちろん、ハッシュ アルゴリズムが複雑すぎると、Hashtable のパフォーマンスにも影響します。
3. HashTable のアプリケーション? HashTable は PHP カーネルにも実装されており、スレッド セーフ、変数ストレージ、リソース管理などに広く使用されています。彼はどこにでもいます。それだけでなく、配列とクラスも PHP スクリプトで広く使用されています。以下では、配列、変数、関数、クラスにおける HashTable の適用に焦点を当てます。
2. 配列に対する HashTable の適用? PHP のほとんどの関数は、配列を含めて HashTable を通じて実装されます。 HashTable は二重リンクリストの利点を持ちながら、データに見合った動作性能を備えています。 PHP で定義された変数はシンボル テーブルに格納されます。このシンボル テーブルは実際には HashTable であり、その各要素は zval* 型の変数です。それだけでなく、ユーザー定義の関数、クラス、リソースなどを格納するコンテナーが HashTable の形式でカーネルに実装されます。
? 以下は PHP で定義された配列です:
?コード マクロ展開:1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
??PHP コードでは、いつでも 2 つの変数シンボル テーブル、symbol_table と active_symbol_table を参照できます。前者はグローバル シンボル テーブルと呼ばれる、グローバル変数を格納するために使用されます。現在のアクティビティ 変数シンボル テーブルは通常、グローバル シンボル テーブルです。ただし、PHP 関数 (ここではユーザーが PHP コードを使用して作成した関数を指します) を入力するたびに、Zend は関数ローカル変数シンボル テーブルを作成し、active_symbol_table がローカル シンボル テーブルを指すようにします。 Zend は常に active_symbol_table を使用して変数にアクセスするため、ローカル変数のスコープ制御を実現します。 ? しかし、グローバルとしてマークされた変数が関数内でローカルにアクセスされると、Zend は特別な処理を実行します。同じ名前の変数が active_symbol_table に存在しない場合は、その変数への参照が作成されます。 symbol_table は最初に作成されます。
? EG マクロを通じて変数シンボル テーブルにアクセスできます。EG (symbol_table) はグローバル スコープの変数シンボル テーブルにアクセスし、EG (active_symbol_table) は現在のスコープの変数シンボル テーブルにアクセスします。
? 上記のコードは非常に単純で、変数 foo を作成し、それを bar に割り当てます。 $foo 変数は、後続の PHP コードで呼び出すことができます。ここで、PHP で定義された変数と、それらがカーネルでどのように実装されるかを見てみましょう。疑似コード:1 |
|
1 |
|
ステップ 2: bar に値を割り当てます。
1 |
|
スコープ シンボル テーブル
に追加すると、ユーザーはこの変数を PHP で使用できるようになります。备注:大家都知道PHP脚本在执行的时候用户全局变量(在用户空间显式定义的变量)会保存在一个HashTable数据类型的符号表(symbol_table)中, 在PHP中有一些比较特殊的全局变量例如: $_GET,$_POST,$_SERVER等变量,我们并没有在程序中定义这些变量,并且这些变量也同样保存在符号表中, 从这些表象我们不难得出结论:PHP是在脚本运行之前就将这些特殊的变量加入到了符号表中了。
四、HashTable在类上的应用
? ? ?类和函数类似,PHP内置及PHP扩展均可以实现自己的内部类,也可以由用户使用PHP代码进行定义。 当然我们在编写代码时通常是自己定义。
? ? ?使用上,我们使用class关键字进行定义,后面接类名,类名可以是任何非PHP保留字的名字。 在类名后面紧跟着一对花括号,里面是类的实体,包括类所具有的属性,这些属性是对象的状态的抽象, 其表现为PHP中支持的数据类型,也可以包括对象本身,通常我们称其为成员变量。 除了类的属性, 类的实体中也包括类所具有的操作,这些操作是对象的行为的抽象,其表现为用操作名和实现该操作的方法, 通常我们称其为成员方法或成员函数。看类示例的代码:
1 |
|
? ??这里定义了一个父类ParentClass,一个接口Ifce,一个子类Tipi。子类继承父类ParentClass, 实现接口Ifce,并且有一个静态变量$sa,一个类常量 CA,一个公用方法,一个私有方法和一个公用静态方法。 这些结构在Zend引擎内部是如何实现的?我们看看类的内部存储结构:
1 |
|
? ? 我们可以看到,在类的实现上,大量使用了hashTable来存储一些类的相关信息,类的属性和方法这些关键信息都是由hashTable存储记录的。
? ? 上面我们列举了hashTable在php应用的几个方面,可以看到hashTable在php内核代码中应用非常广泛,所以有必要深入了解一下hashTable是如何实现的,这对我们深入理解php有很大的帮助。