現在の位置: ホーム> 最新記事一覧> 大きなファイルでmd5_file()を使用した場合はどうすればよいですか?

大きなファイルでmd5_file()を使用した場合はどうすればよいですか?

M66 2025-05-28

PHPでは、 MD5_FILEはファイルのMD5ハッシュ値を計算するための非常に便利な機能です。その使用法は簡単です。ファイルパスに渡すだけです。

 $hash = md5_file('http://m66.net/path/to/largefile.zip');
echo $hash;

ただし、ファイルが非常に大きい場合、 MD5_FILEを使用するとメモリサージが発生し、メモリオーバーフローエラーをトリガーすることさえあります。これは、PHPが内部的にファイル全体をメモリに読み込もうとしているためです。特にリモートURLである場合は、多くのメモリを消費しやすいためです。


なぜMD5_Fileが記憶に急増しているのですか?

md5_fileは簡単な機能ですが、実際に基礎となる層で動作するときにファイル全体をバッファリングすることがよくあります。数百メガバイトまたは数GBの大きなファイルの場合、メモリフットプリントは非常に高く、PHPのメモリ制限を超えることができます。


より多くのメモリを節約する代替品

メモリサージを回避するために、チャンクでファイルストリームを読み取り、セグメントでMD5を計算するソリューションを実装できます。このようにして、少数のデータのみが一度に読み取られ、メモリの使用量は非常に低くなります。

スキームの例:

 function md5_file_stream(string $filename): string|false {
    // リモートの場合URL,最初に、プロトコルヘッダーがサポートするかどうかを確認します
    $context = stream_context_create([
        'http' => ['method' => 'GET', 'timeout' => 10]
    ]);

    // ファイルストリームを開いてみてください
    $fp = fopen($filename, 'rb', false, $context);
    if (!$fp) {
        return false;
    }

    $hashContext = hash_init('md5');

    while (!feof($fp)) {
        // それぞれ読みます8KB,低メモリ圧力
        $data = fread($fp, 8192);
        if ($data === false) {
            fclose($fp);
            return false;
        }
        hash_update($hashContext, $data);
    }

    fclose($fp);

    return hash_final($hashContext);
}

// 使用の例
$url = 'http://m66.net/path/to/largefile.zip';
$md5 = md5_file_stream($url);
if ($md5 !== false) {
    echo "提出 MD5 値はです:$md5\n";
} else {
    echo "ファイルまたは計算されたエラーの読み取りに失敗しました。\n";
}

プログラムの利点

  • メモリの保存:一度に少量のデータのみを読むだけで、メモリの使用量は安定しています。

  • 大規模なファイルに適用できます:ローカルおよびリモートの大きなファイルのハッシュ計算をサポートします。

  • 柔軟性が高い:読み取りブロックサイズを調整し(16kb、32kbなど)、さまざまなシナリオに適応できます。


要約します

MD5で計算する必要がある大きなファイルとMD5_FILEメモリの使用量が高すぎる場合、チャンク読み取りを使用してハッシュを計算することがより良い選択です。メモリの爆発を回避するだけでなく、コードをシンプルで効率的に保ちます。