PHPでは、 MD5_FILE()関数が特定のファイルのMD5ハッシュ値を計算するために使用され、ファイルの整合性を確認するために、またはファイルコンテンツを一意に識別するためによく使用されます。使用するのはシンプルで便利ですが、 MD5_File()を高い並行性環境で呼び出す場合、開発者はパフォーマンスのボトルネックや不正確な結果を避けるために、いくつかの潜在的な問題に注意を払う必要があります。
md5_file()は基本的にファイルのコンテンツを読み取り、ハッシュ値を計算します。同時環境では、複数のプロセスまたはスレッドが同じファイルに同時に読み書きされた場合、以下につながる可能性があります。
不完全または書かれたデータが読み取られるため、計算されたMD5値は不正確です。
ファイルはロックするために書き込まれているため、読み取り操作がブロックされ、並行性パフォーマンスに影響します。
解決:
ファイルを作成するときは、ファイルロック( Flock() )を使用して、書き込みが完了した後にのみロックがリリースされることを確認し、同時読み取り中に半仕上げのファイルを取得しないようにします。
読み取りの場合、ロックも追加されるか、メカニズムを使用してファイルが書き込まれ、MD5が計算されます。
$filename = '/path/to/file.txt';
// 書くときにロックします
$file = fopen($filename, 'c+');
if (flock($file, LOCK_EX)) {
ftruncate($file, 0);
fwrite($file, '新しいコンテンツ');
fflush($file);
flock($file, LOCK_UN);
}
fclose($file);
// 読書中にロックが追加され、読書中に書かれないように
$file = fopen($filename, 'r');
if (flock($file, LOCK_SH)) {
$md5 = md5_file($filename);
flock($file, LOCK_UN);
}
fclose($file);
echo "提出MD5価値: " . $md5;
一部のオペレーティングシステムまたはファイルシステムには、ファイル操作のキャッシュメカニズムがある場合があり、ファイルの変更後すぐに古いデータが読み取られ、 MD5_File()の精度に影響します。
解決:
ClearStatCache()関数を使用して、ファイル状態のキャッシュをクリーニングして、最新のファイル状態が読み取られるようにします。
clearstatcache(true, $filename);
$md5 = md5_file($filename);
md5_file()は、ファイルコンテンツ全体を読み取ります。ファイルが大きい場合、または通話周波数が非常に高い場合、I/Oボトルネックに簡単につながり、システム全体のパフォーマンスに影響を与える可能性があります。
最適化の提案:
ファイルが変更されたかどうかを確認するだけで、ファイルの変更時間FILEMTIME()およびファイルサイズFilesize()に基づいて予備判断を下すことができます。ファイルの変更が確認された場合にのみ、 md5_file()を呼び出します。
より効率的な非同期処理またはキューイングメカニズムを使用して、頻繁な計算を避けます。
大きなファイルの場合、チャンクされたコンピューティングハッシュを検討するか、より効率的なハッシュアルゴリズムを使用することができます。
$filename = '/path/to/file.txt';
$lastMtime = 0;
$lastFilesize = 0;
$lastMd5 = '';
$currentMtime = filemtime($filename);
$currentFilesize = filesize($filename);
if ($currentMtime !== $lastMtime || $currentFilesize !== $lastFilesize) {
clearstatcache(true, $filename);
$lastMd5 = md5_file($filename);
$lastMtime = $currentMtime;
$lastFilesize = $currentFilesize;
}
echo "書類MD5: " . $lastMd5;
分散型またはマルチプロセス環境では、ローカルファイルロックのみに依存すると、複数のインスタンス間の原子操作が保証されない場合があります。現時点では、以下など、より高度な同期メカニズムが必要です。
分散ロック(Redis、Zookeeperなどに基づくロックメカニズムなど)を使用します。
ファイル処理のタスクキューを設計して、同時にプロセス動作ファイルが1つしかないことを確認します。
ファイルパスがURL(リモートファイルなど)に基づいて取得されている場合は、次のことをご覧ください。
ネットワーク要求の安定性とタイムアウト処理。
リモートファイルのコンテンツが変更される場合があり、 MD5_FILE()を呼び出すには、リモートサーバーがサポートし、ファイルの読み取りを許可することを確認する必要があります。
ここでドメイン名を置き換える必要がある場合、この例では、ドメイン名がM66.netに置き換えられます。