0
파일이있는 서버가 있으며 사람들이 파일을 다운로드 할 수 있습니다. 나는 다운로드 보내려면이 코드를 사용 : 내 브라우저 모두를 통해 파일을 다운로드 할 때다운로드 관리자가 PHP 다운로드를 99 % 중단합니다.
<?php
function dl_file_resumable($file, $is_resume = true)
{
//First, see if the file exists
if (!is_file($file)) {
header("HTTP/1.1 400 Invalid Request");
die("<h3>File Not Found</h3>");
}
//Gather relevent info about file
$size = filesize($file);
$fileinfo = pathinfo($file);
//workaround for IE filename bug with multiple periods/multiple dots in filename
//that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe
$filename = (isset($_SERVER['HTTP_USER_AGENT']) && strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) ?
preg_replace('/\./', '%2e', $fileinfo['basename'], substr_count($fileinfo['basename'], '.') - 1) :
$fileinfo['basename'];
$file_extension = strtolower($fileinfo['extension']);
//This will set the Content-Type to the appropriate setting for the file
require 'mineTypes.php';
// Check if the file extension is in $ctype_array & return the value. If not, send default.
$ctype = array_key_exists($file_extension, $ctype_array) ? $ctype_array[$file_extension] : 'application/force-download';
$is_resume = ($is_resume && isset($_SERVER['HTTP_RANGE']));
//check if http_range is sent by browser (or download manager)
if($is_resume)
{
$arr = explode('=', $_SERVER['HTTP_RANGE'], 2);
if(isset($arr[1]))
list($size_unit, $range_orig) = $arr;
else list($size_unit) = $arr;
if ($size_unit == 'bytes')
{
//multiple ranges could be specified at the same time, but for simplicity only serve the first range
//http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
$arr3 = explode(',', $range_orig, 2);
if(isset($arr3[1]))
list($range, $extra_ranges) = $arr3;
else
list($range) = $arr3;
}
else
{
$range = '';
}
}
else
{
$range = '';
}
//figure out download piece from range (if set)
$arr2 = explode('-', $range, 2);
if(isset($arr2[1]))
list($seek_start, $seek_end) = $arr2;
else
list($seek_start) = $arr2;
//set start and end based on range (if set), else set defaults
//also check for invalid ranges.
$seek_end = (empty($seek_end)) ? ($size - 1) : min(abs(intval($seek_end)),($size - 1));
$seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0);
//add headers if resumable
if ($is_resume)
{
//Only send partial content header if downloading a piece of the file (IE workaround)
if ($seek_start > 0 || $seek_end < ($size - 1))
{
header('HTTP/1.1 206 Partial Content');
}
header('Accept-Ranges: bytes');
header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$size);
}
header('Content-Type: ' . $ctype);
header('Content-Length: '.($seek_end - $seek_start + 1));
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Accept-Ranges: bytes');
//reset time limit for big files
set_time_limit(0);
//open the file
$fp = fopen($file, 'rb');
//seek to start of missing part
fseek($fp, $seek_start);
//start buffered download
$bytes = 0;
while(!feof($fp))
{
print(fread($fp, 1024*8));
flush();
$bytes = $bytes + 1024 * 8;
ob_flush();
}
fclose($fp);
exit;
}
하는 것은 괜찮지 만, 내가 (IDM 같은) 다운로드 관리자를 통해 다운로드 할 때 - 다운로드가 99 %에서 멈 춥니 다.
무엇이 잘못 되었나요?
만약 있기 때문에,
flush
에드하지 않습니다, 그것은 클라이언트 양면 문제입니다. 다른 다운로드 관리자를 사용해보십시오. 사용중인 관리자와 문제가있을 수 있습니다. –@DaveChen 다른 사람들에게도 마찬가지입니다. – HtmHell
나는이 문제에 대해 디버깅을해야 할 것 같습니다. 커맨드 라인에서'wget'을 시도하면 요청으로 범위 헤더를 보낼 수 있어야합니다. 모든 전체 청크가 정상적으로 작동 할 것으로 기대하지만, 마지막 (불완전한) 항목은 어떤 식 으로든 손상됩니다. 해당 부분의 응답 헤더에있는 내용을 확인하십시오. – halfer