我的服务器有客户端下载限制。我的服务器允许客户端下载少于4mb的文件。如果文件较大,则服务器终止下载过程。因此,我想使用范围来分割文件大小,逐块下载大文件。服务器不允许下载更大尺寸的文件,因此,当php代码在同一页面中输出所有块缓冲区时,服务器会捕获更大的文件。所以我想用3.999mb将缓冲区页面刷新3.999mb。每次将加载3.999mb缓冲区时,我将能够通过合并下载完整文件,然后再将块下载到新请求的下一个块中。
示例:
文件总大小为:10mb,现在我要开始下载第一个块 3.999mb,然后自动刷新带有新请求的页面,下一个3.999mb范围,该下一个范围将与第一个3.999mb合并,然后自动刷新,并显示下一个新请求 范围为2.2mb,并在下载7.998mb之前将其合并。下载总数 10mb(完整文件)。
注意:我不想使用javascript自动刷新(我的工作不支持javascript)。我想使用php 自动刷新到新的请求/加载下一个范围。
我尝试使用下面的代码来做到这一点,但是下面的代码只是下载了第一个块,并且在下载过程中不根据新请求刷新下一个范围。
<?php
session_start();
if (!isset($_SESSION['ranges'])) $_SESSION['ranges'] = 0;
ini_set('max_execution_time', 0);
$url = $_GET['url'];
$filesize = getSizeFile($url);
$chunksize = (4*1024*1024)-1;
$splits = range(0, $filesize, round($chunksize));
$ranges = '';
for($i = 0; $i<sizeof($splits); $i++)
{
$x = ($i == 0 ? 0 : $splits[$i]+1);
$y = ($i == sizeof($splits)-1 ? $filesize : $splits[$i+1]);
$ranges .= $x.'-'.$y.' ';
}
$range = explode(' ', $ranges);
$size = ++$_SESSION['ranges'] % count($range)-1;
$reloadRange = $range[$size];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, 'opera mini android');
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt ($ch, CURLOPT_HTTPHEADER, array(
"HTTP/1.1 206 Partial Content",
"Server: Apache",
"Accept-Ranges: bytes",
"Range: bytes= $reloadRange"
));
$result = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$body = substr($result, $header_size);
curl_close($ch);
ob_start();
echo $body;
$b = ob_get_length();
if(explode('-', $reloadRange)[0] == 0)
{
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($url));
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
}
if(explode('-', $reloadRange)[1] !== getSizeFile($url))
{
if($b !== null)
{
header("Refresh: 0;");
//header('Refresh: 0; url=/server/tt?url='.$url);
exit();
} else {
exit;
}
} else {
session_destroy();
session_write_close();
exit;
}
function getSizeFile($url) {
if (substr($url,0,4)=='http') {
$x = array_change_key_case(get_headers($url, 1),CASE_LOWER);
if ( strcasecmp($x[0], 'HTTP/1.1 200 OK') != 0 ) { $x = $x['content-length'][1]; }
else { $x = $x['content-length']; }
}
else { $x = @filesize($url); }
return $x;
}
?>
谢谢