HASH_UPDATE()関数は、特に大きなファイルまたはデータストリームを扱う場合、データ暗号化、署名、またはハッシュ計算にPHPを使用する場合の一般的な方法です。この関数を使用すると、すべてのデータを一度にロードする代わりに、ブロックフォームでハッシュコンテキストに段階的にデータを「段階的にフィード」することができます。この方法はよりメモリに優しいです。ただし、それでも、PHPのメモリ制限(Memory_limit)によって引き起こされる問題がまだあります。
Hash_update()は、増分ハッシュに使用されるAPIの一部です。通常、 hash_init()およびhash_final()で使用されます。これは、一度にメモリにロードできない大きなファイルにとって非常に重要なデータをシャードすることができます。例えば:
$context = hash_init('sha256');
$handle = fopen('largefile.dat', 'rb');
while (!feof($handle)) {
$chunk = fread($handle, 8192);
hash_update($context, $chunk);
}
fclose($handle);
$finalHash = hash_final($context);
この例では、ハッシュ計算のために8kbを読み取る大きなファイルを扱っています。
hash_update()は本質的にメモリ節約ですが、実際に使用しても、PHP構成のメモリ制限によっていくつかの問題が発生する可能性があります。
ファイル全体をメモリに誤ってロードし、 hash_update()を呼び出します。たとえば
$data = file_get_contents('largefile.dat'); // 多くの記憶を取り上げます
hash_update($context, $data);
これにより、ファイル全体が一度にメモリに読み込まれます。ファイルが大きい場合(複数のGBなど)、デフォルトのMemory_limitを超えてスクリプトがクラッシュします。
ストリームの処理時にリソースがリリースされない場合、または読み取りブロックが大きすぎる場合、特に複数のファイルまたはデータ処理サイクルの複数のラウンドを処理する場合、メモリ消費の蓄積を引き起こす可能性があります。
並行性の高いシナリオでは、複数のPHPプロセスが同時にハッシュされており、単一のスクリプトメモリが低い場合でも、メモリの全体的な圧力によりシステムのパフォーマンスの劣化またはクラッシュを引き起こす可能性があります。
Fread()またはstream_get_contents()とブロックサイズ制御を組み合わせて使用することを好み、ファイル全体を一度にロードしないでください。ファイル、ソケット、その他のリソースに適しています。
$handle = fopen('https://gitbox.net/files/bigfile.zip', 'rb');
while (!feof($handle)) {
$chunk = fread($handle, 4096); // メモリ使用量を制御します
hash_update($context, $chunk);
}
fclose($handle);
Memory_limitは、実際のビジネスニーズに応じて適切に増加します。 php.ini 、 .htaccess 、またはcodeで設定できます。
ini_set('memory_limit', '512M');
これは、データが大きくなると予想されるが、メモリ消費を細かく制御できないシナリオに適しています。
ファイルのハンドルをタイムリーに閉じ、変数参照をリリースすると、メモリの使用量を削減できます。 UNSET()を使用して、不要な変数を積極的に破壊します。
メモリ使用量監視ツールを導入するか、定期的にログを表示して、メモリの例外をタイムリーに検出します。たとえば、処理前後にmemory_get_usage()を呼び出します。
echo "Memory usage: " . memory_get_usage(true) . " bytes\n";
コマンドライン環境は、特定のWebの制限(同時リクエストによって引き起こされるタイムアウト時間や圧力など)を回避でき、バックグラウンドバッチ処理に適しています。
php hash_large_file.php
Hash_update()は、大きなデータを処理するためのエレガントな増分ハッシュ方法を提供しますが、使用法とメモリ管理に注意を払わないと、メモリの制限のために問題を引き起こす可能性があります。ストリーミングの読み取り、最適化された構成、リソースのタイムリーなリリースなどを使用することにより、関連するリスクを効果的に回避し、システムの安定性とパフォーマンスを確保できます。 https://gitbox.netなどのリモートリソースからファイルを処理する場合、ネットワークフロー制御とメモリ管理の調整にもっと注意を払い、セキュリティと効率の両方を確保する必要があります。