PHPの超大きいファイルのダウンロードを解決して、ブレークポイントの継続的なダウンロードの方法の詳しい解

3411 ワード

最近、エクスポート時にphpメモリが溢れているという問題が発生したのは、ダウンロード時に読み込まれて生成されたテンポラリファイルが大きすぎてPHPメモリが収まらず、いったんPHPメモリの制限を変更しようとしたが、これはただの緩兵の計で、もう一つの方法はファイルを分割して読み取り、ダウンロードすることだと考えたからだ.
ソースコードは次のとおりです.
 
  
$sourceFile = "1.tmp"; //
$outFile = " .xls"; //
$file_extension = strtolower(substr(strrchr($sourceFile, "."), 1)); //
//echo $sourceFile;
if (!ereg("[tmp|txt|rar|pdf|doc]", $file_extension))exit (" ");
//
if (!is_file($sourceFile)) {
die("404 File not found!");
}
$len = filesize($sourceFile); //
$filename = basename($sourceFile); //
$outFile_extension = strtolower(substr(strrchr($outFile, "."), 1)); //
//
switch ($outFile_extension) {
case "exe" :
$ctype = "application/octet-stream";
break;
case "zip" :
$ctype = "application/zip";
break;
case "mp3" :
$ctype = "audio/mpeg";
break;
case "mpg" :
$ctype = "video/mpeg";
break;
case "avi" :
$ctype = "video/x-msvideo";
break;
default :
$ctype = "application/force-download";
}
//Begin writing headers
header("Cache-Control:");
header("Cache-Control: public");
//
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=" . $outFile);
header("Accept-Ranges: bytes");
$size = filesize($sourceFile);
// $_SERVER['HTTP_RANGE']
if (isset ($_SERVER['HTTP_RANGE'])) {
/*Range Range 。

500 :bytes=0-499
500 :bytes=500-999
500 :bytes=-500
500 :bytes=500-
:bytes=0-0,-1
:bytes=500-600,601-999
, GET Range , 206(PartialContent) 200 (OK)。
*/
// $_SERVER['HTTP_RANGE'] bytes=4390912-
list ($a, $range) = explode("=", $_SERVER['HTTP_RANGE']);
//if yes, download missing part
str_replace($range, "-", $range); // 。。。。
$size2 = $size -1; //
$new_length = $size2 - $range; //
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length"); //
header("Content-Range: bytes $range$size2/$size"); //Content-Range: bytes 4908618-4988927/4988928 95%
} else {
//
$size2 = $size -1;
header("Content-Range: bytes 0-$size2/$size"); //Content-Range: bytes 0-4988927/4988928
header("Content-Length: " . $size); //
}
//
$fp = fopen("$sourceFile", "rb");
//
fseek($fp, $range);
//
while (!feof($fp)) {
//
set_time_limit(0);
print (fread($fp, 1024 * 8)); //
flush(); //
ob_flush();
}
fclose($fp);
exit ();