開発プロセス中、大規模なファイルをダウンロードする必要性に遭遇すると、PHPのReadFile()関数を使用するのは簡単ですが、非常に大きなファイルの場合、ファイル出力全体を直接読み取ると、メモリの使用量が過剰になります。したがって、プログラムの安定性とユーザーエクスペリエンスを確保するために、より効率的なダウンロードソリューションを採用する必要があります。
BreakPointの継続により、完成した部品を繰り返しダウンロードすることなく、ダウンロードが中断された後、ユーザーが割り込みの場所からダウンロードを続けることができます。これにより、帯域幅を節約するだけでなく、特にネットワーク環境が不安定な場合、ダウンロードの信頼性とユーザーの満足度が向上します。
まず、 $ _GETを使用してクライアントによって渡されたファイルパスパラメーターを取得し、 Basename()関数を使用してファイル名を抽出して、ディレクトリの交差などのセキュリティリスクを回避します。
$file = $_GET['file'];
$filename = basename($file);
これは、コンテンツタイプをApplication/Octet-Streamに設定することにより、これがバイナリファイルストリームであることをブラウザに伝えます。また、添付ファイルのダウンロードとファイル名を示すように、コンテンツ拡散ヘッダーを設定します。
リクエストヘッダーのhttp_rangeによると、ダウンロード開始場所は解析され、ファイルポインターはfseek()を使用して調整され、ブレークポイントの連続伝送を実現します。
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
preg_match('/bytes=(\d+)-/', $range, $matches);
$start = intval($matches[1]);
fseek($file, $start);
}
ファイルコンテンツをループすることにより、毎回特定のサイズ(たとえば4096バイト)のバッファーを読み取り、徐々にブラウザに出力し、出力バッファを更新してデータのタイムリーな送信を確保します。
$buffer_size = 4096;
while (!feof($file)) {
echo fread($file, $buffer_size);
ob_flush();
flush();
}
上記の方法により、PHPは、スーパーレージファイルのブレークポイントの中断を効率的にサポートでき、大規模なファイル処理での従来のReadFile()関数の欠点を解決できます。開発者は、ユーザーエクスペリエンスをさらに向上させるために、これに基づいてダウンロードプログレスディスプレイ、速度制限制御、その他の機能を実装することもできます。
HTTPプロトコルの範囲ヘッダーとPHPファイル操作関数の合理的な使用により、ダウンロードサービスがより安定して柔軟になり、さまざまな実用的なビジネスシナリオに適しています。