基本を超えて:PHPのアレイ内部に深く飛び込む
PHPアレイは、従来の連続メモリアレイではなく、本質的に順序付けられたハッシュテーブルです。 1.ハッシュ関数を介したO(1)平均検索を実現し、双方向のリンクリストで挿入順序を維持します。 2。各要素は、キー、ハッシュ値、ZVALへのポインター、リンクされたリストポインターなど、バケツに保存されます。 3.キータイプは自動的に変換されます。文字列番号は整数に、フローティングポイントの切り捨て、ブール値は0/1に、nullから空の文字列。 4.各要素は多くのメモリを消費します(ZVALは約16〜24バイト、バケットは約72バイトです)。 5。リーチトラバーサルはリンクリストに基づいており、順序は安定していますが、array_reverseを再構築する必要があります。 6.ハッシュ競合は、ルックアップをO(n)に変化させる可能性があり、PHP 7.2は無作為化ハッシュ防御衝突攻撃を導入します。 7。配列の割り当ては、コピーオンワイト(牛)を使用し、参照は同じハッシュテーブルを共有します。 8。実際の開発では、大規模なデータを配列にロードすることを避け、ジェネレーターの使用を優先し、array_key_existsとarray_keysを注意し、存在チェックのためにISSETを推奨する必要があります。これらのメカニズムを理解することで、パフォーマンスとメモリの使用量を最適化し、最終的に効率的なPHPプログラミングを実装します。
毎日PHPアレイを使用すると、当たり前のことと思っています。それらは柔軟です - リスト、辞書、スタック、または擬似オブジェクトとして使用されます。しかし、ボンネットではどうなりますか?特に高負荷アプリケーションでは、PHPのパフォーマンスとメモリの使用量を真にマスターするには、基本を超えてPHPのアレイ内部を理解する必要があります。

Cなどの低レベルの言語のアレイとは異なり、PHPアレイはメモリの単純な連続ブロックではありません。代わりに、それらは順序付けられたハッシュテーブルとして実装されます。これは、高速キー価値のルックアップと順序付けられたトラバーサルの両方を可能にする強力なハイブリッド構造です。これがどのように機能するかを分解しましょう。
PHPアレイが実際にハッシュテーブルである方法
コアでは、PHPアレイは順序付けられたハッシュテーブル(リンクリストを持つハッシュテーブルとも呼ばれます)です。この二重の性質は次のことを可能にします:

- 高速キーベースのアクセス(平均O(1)ハッシュ経由のルックアップ)
- 維持された挿入順序(二重リンクリスト経由)
これがあなたができる理由です:
$ array ['name'] = 'john'; $ array [42] = 'Answer'; $ array ['3.14'] = 'pi';
…そして、PHPは文字列、整数、さらには数値文字列をシームレスに処理します。

内部的には、PHPはZend Engineのハッシュテーブル構造を使用します。
- キーをバケツにマッピングするハッシュ関数
- キー価値ペア(zvals)を保存するバケット
- 挿入順序でエントリを接続するダブルリンクリスト
- 高速インデックス作成のためのサイズフィールドとハッシュテーブルマスク
配列内の各要素はバケットに保存され、バケツはキーのハッシュに基づいてハッシュテーブルアレイにグループ化されます。衝突(2つのキーが同じインデックスにハッシュする場合)は、チェーンを介して解決されます。
重要な内部:ZVAL、バケット、およびジャグリングタイプ
1。ZVALS :ユニバーサルバリューコンテナ
PHPのすべての値(int、string、またはobject)は、 zval
(zend値)に保存されています。 PHP 7では、 zval
は次のようなコンパクトな構造体です。
- 実際の値(またはポインター)
- タイプタグ(例:is_long、is_string)
- 参照カウント(GCの場合)
- ごみ収集情報
アレイに値を割り当てるとき:
$ arr ['key'] = 42;
PHPは、タイプIS_LONG
と値42
搭載したZVALを作成し、ハッシュテーブルに保存します。
2。バケツ:キーと価値のペアがライブ
ハッシュテーブルの各バケットには次のものが含まれています。
- キーのハッシュ
- キー自体(文字列または数値のいずれか)
- Zvalへのポインタ
- 衝突チェーンの次のポイント
- H(整数のようなキーに使用される数値ハッシュキー)
文字列キーの場合、完全な文字列が保存されます。数値キー(弦楽額を含む)の場合、PHPは可能な場合は内部的に整数に正規化します。
3。キーの強制を入力します
PHPは静かに配列キーを正常化します:
$ arr [1] = 'one'; $ arr ['1'] = 'string one'; //前に上書きします! $ arr [1.9] = 'float'; //キー1になり、もう一度上書きします
これは次のとおりです。
- 数値に見える文字列キー→整数に変換されます
- フロート→整数に切り捨てられます(丸くない!)
-
true
→1、false
→0、null
→ ''(空の文字列)
したがって、ハッシュテーブルは長いまたはひもキーのみを許可します。他のすべてのものが強制されます。
メモリオーバーヘッド:大きなアレイが高価な理由
PHPアレイは単なるデータではなく、メタデータが多いです。各要素について、あなたは保存しています:
成分 | 約サイズ(64ビット) |
---|---|
zval | 16〜24バイト |
バケツ | 〜72バイト |
キー文字列(ある場合) | 文字列1のサイズ |
ハッシュテーブルオーバーヘッド | アレイごとに〜72バイト |
だから、次のような単純な配列
$ array = [1、2、3];
…3つの整数だけでなく、数百バイトを使用する場合があります。
これが、PHPアレイに100,000行をロードすると、数十メガバイトを消費できる理由です。
?ヒント:可能な場合はすべてを配列にロードする代わりに、ジェネレーターまたは反復処理を使用します。
パフォーマンスへの影響
反復順序は予測可能です(ただし無料ではありません)
PHPアレイは、リンクリストを介して挿入順序を維持するため、 foreach
高速で一貫しています。
foreach($ array as $ key => $ value){...}
内部的には、PHPはハッシュテーブルではなく、リンクされたバケツのリストに従います。そのため、順序は並べ替えずに保存されます。
しかし、これも意味します:
-
array_reverse()
ハッシュテーブル全体を再構築する必要があります(o(n)) -
ksort()
キーに基づいてリンクされたリストを再配置しますが、再ハッシュしません
ハッシュの衝突により、物事が遅くなる可能性があります
最悪のシナリオ(例えば、多くの衝突キー)では、ルックアップはO(1)の代わりにO(n)に分解されます。実際にはまれですが、これはハッシュ衝突攻撃で活用される可能性があります(古いPHPバージョンのセキュリティ上の懸念)。
PHPは、予測可能な衝突を防ぐために、ランダム化ハッシュ関数(7.2以降)を使用するようになりました。
高度な動作:参照とコピーオンワイト
PHPアレイは、コピーオンワイト(牛)セマンティクスを使用します。
$ a = [1、2、3]; $ b = $ a; //まだコピーがありません $ b [] = 4; // $ bは本物のコピーを取得します
フードの下:
-
$a
と$b
両方が同じハッシュテーブルを指します refcount
が増加します- 1つが変更された場合にのみ、PHPは完全なコピーを作成します
しかし、参照があります:
$ b =&$ a; //今、彼らは書き込みでも共有しています
エンジンはこれを追跡し、コピーを回避します。
これにより、配列の割り当てが効率的になりますが、コピーがいつ発生するかわからない場合は、微妙なバグを引き起こす可能性があります。
実用的な持ち帰り
PHPの配列内部を理解することで、より良い、より効率的なコードを書き込むのに役立ちます。
- memoryメモリ内の巨大な配列を避ける- ジェネレーター、イテレーター、またはチャンクで処理する
- Arrayキーに注意してください- 数値文字列は整数になり、上書きを引き起こす可能性があります
- hassed可能な場合は、
array_key_exists()
よりもisset()
を好みますisset()
はハッシュテーブルを直接使用します(より速く) -
array_keys($arr, $search)
慎重に使用します- それはo(n)であり、ハッシュによって最適化されていません - ✅メモリの使用量が少ないと仮定しないでください- アレイは強力ですが高価です
基本的に、PHPアレイは従来の意味での配列ではありません。それらは洗練され、柔軟で、便利ですが、記憶とパフォーマンスのトレードオフが伴います。それらがどのように機能するかを知ることで、特にスケーリングするときは、それらを賢く使用できます。
それは魔法ではありません。リンクされたリストがあり、多くの巧妙なエンジニアリングを備えたハッシュテーブルです。しかし今、あなたは$arr['hello'] = 'world';
。
以上が基本を超えて:PHPのアレイ内部に深く飛び込むの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undress AI Tool
脱衣画像を無料で

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











upgradephp7.xcodebasestophp8 byreplacingphpdoc-suggestedtypeslike@paramstring | intwithnativeuniontypessuchasstring | intforparametersandreturntypes、whithemprovestypeSafetyandclarity;

PHPは、ゆるいタイプと厳格なタイプの共存をサポートします。これは、スクリプト言語から最新のプログラミング言語への進化の中心的な特徴です。 1.ゆるいタイプは、迅速なプロトタイピング、動的なユーザー入力の処理、または外部APIでのドッキングに適していますが、暗黙のタイプ変換のリスク、デバッグの難しさ、ツールサポートの弱いなどの問題があります。 2。decrare(strict_types = 1)で厳密なタイプが有効になります。これは、事前にエラーを検出し、コードの読みやすさとIDEサポートを改善することができ、コアビジネスロジック、チームコラボレーション、データの整合性の高い要件を備えたシナリオに適しています。 3。実際の開発で混合使用を使用する必要があります。デフォルトでは厳密なタイプが有効になり、緩いタイプは入力境界で必要な場合にのみ使用され、検証とタイプ変換はできるだけ早く実行されます。 4.推奨されるプラクティスには、PHPSTAの使用が含まれます

0.1 0.2!== 0.3inphpduetobinary floating-precisionlimitations、sodevelopersmustavoiddirectcomparisonsandusepsilonベースのチェック、empluebcmathorgmtic、emplovebcmathorgmetic、storecurrencyinintegersegorsible、formatutcoputputputputputtutputpotised、およびneverrelelelyonfrocisis

acallable inphpisapsapsodo-typereprepreSentingnayvaluethatcanbeedusings the()演算子は、主に使用されています

returntypesinphpimprovecoderiability andclaritybysifyifiecifyive whatafunctionmusterturn.2.usebasictypeslikestring、array、ordatetimetoenforcorcreturnvaluesandcatcherrorsearly.3.ApplynullabletypeSwith?(E.G。、?

php8.1で導入された酵素は、魔法の価値の問題を解決するタイプセーフ定数コレクションを提供します。 1. enumを使用して、ステータス::ドラフトなどの固定定数を定義して、定義された値のみが利用可能であることを確認します。 2。列挙型をバックデナムに介して弦または整数にバインドし、スカラーと酵素間の()とtryfrom()からの変換をサポートします。 3。酵素は、ビジネスロジックのカプセル化を強化するために、color()やisedable()などの方法と動作を定義できます。 4。動的データではなく、状態や構成などの静的シナリオに適用できます。 5.タイプの制約のためにUnitenumまたはBackedenumインターフェイスを実装し、コードの堅牢性とIDEサポートを改善し、

PHPはZVAL構造を使用して変数を管理します。答えは次のとおりです。1。ZValには、16バイトのサイズの値、タイプ、メタデータが含まれています。 2。タイプが変更されたら、組合とタイプ情報のみを更新する必要があります。 3。複雑なタイプは、ポインターを介した参照カウントを持つ構造を指します。 4.値を割り当てるとき、コピーを使用してメモリを最適化します。 5。参照変数が同じZVALを共有するようにします。 6.リサイクル参照は、特別なゴミコレクターによって処理されます。これは、PHP変数の動作の根本的なメカニズムを説明しています。

PHPリソースのライフサイクルは、次の3つの段階に分けられます。1。リソース作成、Fopenやcurl_initなどの関数を介して外部システムハンドルを取得します。 2。リソースの使用、操作のための関連関数にリソースを渡す、PHPはリソースIDを介して基礎となるシステム構造にマップします。 3。ファイル記述子が消耗しないように、自動ガーベージコレクションに依存しないように、リソースをリリースするために、Fclose、curl_close、およびその他の機能を手動で呼び出すリソースの破壊を優先する必要があります。ベストプラクティスは次のとおりです。常に明示的にリソースを閉じ、試してみてください...最後にクリーンアップを確保し、__DestructをサポートするPDOなどのオブジェクトに優先順位を付け、グローバルストレージリソースを避け、get_resources()を介してアクティブリソースを監視する
