【PHP学習】PHP7のデータ型

little bottle
little bottle転載
2019-04-18 16:29:472056ブラウズ

PHP の変数名 → zval、変数値 → zend_value。その変数メモリは参照カウントによって管理されます。PHP7 では、参照カウントは値構造内にあります。

変数タイプ:

ヘッダー ファイルは PHP ソース コード/zend/zend_types.h

:

## に内部的に実装されます。 # PHP は zval 構造体を通じて変数を表し、さまざまな型の変数値は zval に埋め込まれた共用体、つまり zend_value を通じて表されます。

## zend_value は共用体であり、そのコードは次のとおりです:

ast 、ptr、zv などの型は、カーネル自体によってのみ使用されます。

文字列:

PHP は文字列用に別の構造体 zend_string を定義します。 zend_value では、str は特定の構造体を指します。

#文字列の内容を格納する val は特別です。

val は char* 型を使用しません。文字列を割り当てるときは、malloc(sizeof(zend_sting) string length) のように操作されます。これは、文字列の内容を保存するためにより多くのメモリが割り当てられることを意味します。このブロックの追加メモリの開始位置は val です。

これの利点は、1 つのメモリ割り当て (char*) を節約でき、メモリ管理に役立つことです。

val の追加バイト (構造内の val[0] ではなく val[1]) は、保存された文字列の最後の文字 "\0" を保存するために使用されます。

たとえば、$a="abc" の場合、対応する zend_string メモリ構造は左のとおりです。

Array:

##nTableMask:この値は、次に従ってハッシュ関数で使用されます。キーのハッシュ コード スネーク要素が位置として保存されるときに使用されます。 nTableMask = -nTableSize または nTableMask = ~nTableSize 1.

nNumused, nNumOfElements:配列要素を削除する場合、要素はすぐには配列から削除されません。代わりに、要素の型は IS_UNDEF としてマークされます。これは使用されるだけです。アレイの容量が制限を超えて拡張する必要がある場合にのみ削除されます。

展開がない場合、nNum Used は常に増加するため、その値は有効な要素数ではありません。 nNumOfElements は配列内の有効な要素の数であるため、nNumOfElements ≤ nNum Used になります。

バケット

構造体には、要素のキーと値が格納されます。 h はハッシュ コードです。キーが数値 (および数値インデックス) の場合、その値は数値インデックスの値になります。キーが文字列の場合、その値は Time33 アルゴリズムによって計算されたハッシュ値になります。文字列キーに基づいて。 h 値は、要素の格納場所をマップするために使用されます。

配列の実装:

ハッシュ テーブルの順序性を実現するために、PHP のハッシュ テーブルはハッシュ関数と要素の間に要素を追加します。配列. レイヤーマッピングテーブル、このマッピングテーブルも配列であり、サイズは要素を格納する配列と同じです。

中間マッピング テーブルは、実際に格納された順序付けされた配列内の要素の添字を格納します。要素は実際の格納配列に順番に挿入され、その配列の添字はハッシュ関数によってハッシュされた位置に格納されます。新しく追加されたマッピングテーブル。

ハッシュ関数: 要素の保存場所はキーに従ってマッピングされます。通常、モジュロがハッシュ関数として使用されます: key-> ;h %nテーブルサイズ。しかし、PHP は別のアプローチ (nIndex = key->h | nTableMask) を採用しています。

この中間マッピング テーブルは PHP 配列の構造には存在せず、実際には arData と一緒に配置されます。配列が初期化されると、バケットを格納するために使用されるメモリが割り当てられ、同時に uint32_t サイズの同じ量のスペースが割り当てられます。次に、要素の配列が格納されている場所に arData をオフセットします。 中間マッピング テーブルには、arData を介して前方にアクセスできます。

ハッシュの競合: 異なるキー値が同じハッシュ値を計算する可能性があり、ハッシュ テーブルに挿入するときに競合が発生します。 table 要素は 1 つだけ格納できます。

解決策: 競合するバケットをリンク リストに文字列化します。つまり、中間マッピング テーブルは、バケットではなくバケットのリンク リストをマップします。検索する場合は、リンク リストを走査し、キーを 1 つずつ比較して見つける必要があります。ターゲット要素。

HashTable は、arData 配列内で競合する要素の保存場所を記録します。

マッピング値を設定するときに、中間マッピング テーブルに設定する位置が、以前に挿入された要素によって占有されていることがわかりました (値が等しくない)初期化された -1)、既存の値を新しく挿入されたバケット (つまり、c が挿入された後の u2.next=0) に保存し、マッピング テーブル内の値を新しいバケットの保存場所に更新します。 (つまり、マッピング テーブルの値: 2)。

リファレンス:

リファレンスは、C 言語のポインターの概念に似た、他の型を指す構造体です。参照型変数を変更すると、その変更は実際に参照される変数に反映されます。

PHP では、$b = &$a など、& 演算子を通じて参照変数が生成されます。実行中、最初に zend_reference 構造体が & 演算の変数に割り当てられます。この構造体は参照です。 type 構造体。zval が埋め込まれており、この zval の値は元の zval の値を指します。その後、元の zval の型は IS_REFERENCE に変更され、元の zval の値は新しく作成された zend_reference 構造体を指します。

例:


$a = date("Y-m");$b = &$a;

$a は、& までの文字列です。 $a は参照型に変換して $b に割り当てます。変換後、$a の型は IS_STRING から IS_REFERENCE に変わり、$a の値も元の文字列を指す zend_reference 構造体に変換されます。

$a と $b は、実際の値を間接的に指します。

参照を使用する場合は注意が必要です。参照は & を通じてのみ生成でき、代入を通じて渡すことはできません。

上記の例のように、$b が他の変数に割り当てられている場合、新しい変数に渡される値は、参照自体ではなく、実際の参照の値になります。


$a = date("Y-m");$b = &$a;$c = $b;   //如果想让$c也引用指向$a/$b引用的值,则:$c = &$b

おすすめコース: PHP ビデオ チュートリアル

以上が【PHP学習】PHP7のデータ型の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。