PHPカーネル探索の変数

3682 ワード

php変数コンポーネント:
変数名:php言語の変数名は$で始まる+英語/下線で、数字、下線、アルファベットを含み、大文字と小文字を区別できます.同時にPHPは$$Aのような複合変数をサポートし,phpのダイナミック性を増加させた.
タイプ:phpは弱いタイプの言語に属し、任意のタイプの値を割り当てることができます.
内容:同じ時刻に1つの値しか持てません.
php言語には8つのデータ型が存在し、3つのクラスに分けられます.
1.スカラータイプ:Boolean、integer、float、string;
2.複合タイプ:object,array;
3.特殊タイプ:NULL,resource;
phpは弱いタイプの言語として、実装内部のすべての変数は構造zvalによってデータを格納し、変数の値だけでなく、変数のタイプも含まれ、phpの弱いタイプの核心である.
zvalデータ構造:

struct _zval_struct{
  zvalue_value value;    //      
  zend_unint  refcount_gc; //    
  zend_char  is_ref_gc;  //      
  zend_char  type;     //       
}

ここでzvalue_valueは構造体ではなく、メモリで使用されるunionを節約するために実現されます.同じ時点で変数は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配列はハッシュ・テーブルを使用して関連データを格納し、ハッシュ・テーブルは2つのデータ構造HashTableとBucketを使用する.
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に近い整数次数に調整される.理由:
スロット選択時には、ここでは型取りではなく&操作を使用します.これは、相対的に型取り操作の消費とビットアンド操作が大きいためです.maskの役割は,ハッシュ値をスロットビットが格納できるインデックス範囲にマッピングすることである.たとえば、あるkeyのインデックス値が21でハッシュテーブルのサイズが8でmaskが7であれば、加算時のバイナリ表現は10101&111=101、すなわち10進数の5である.2の整数次数-1のバイナリは特殊なので、後ろのNビットの値はすべて1で、このように比較的に値をマッピングすることができやすくて、普通の数字がバイナリを行った場合と後でハッシュ値の結果に影響します.ハッシュ関数が計算した値の平均分布に影響を及ぼす可能性がある.
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; 

Bucketにはハッシュのインデックスではなくハッシュ値が格納されます.
上の構造体の最後のフィールドはkeyの文字列を保存するために使用されますが、このフィールドは1つの文字しかない配列であることを示しています.実は、ここは長見の変長構造体で、主な目的は柔軟性を高めることです.ハッシュ・テーブルが新しい要素を挿入したときの申請空間のコードを次に示します.

p = (Bucket *) pemalloc(sizeof(Bucket) - 1 + nKeyLength, ht->persistent);
if (!p) {
  return FAILURE;
}
memcpy(p->arKey, arKey, nKeyLength);


プロセス図の挿入
ハッシュアルゴリズム
phpにおけるhash関数はDJBX 33 Aアルゴリズムを用いて実現した.
オブジェクト:
phpオブジェクト使用データ構造zend_object_valueは格納します.