Мой сервер имеет ограничение загрузки клиента. Мой сервер позволяет клиенту загружать менее 4 Мб файла. Если размер файла больше, то процесс загрузки уничтожается сервером. Поэтому я хотел загрузить большой кусок файла по частям, используя диапазон, чтобы разделить размеры файлов. Сервер не допускает загрузку файлов большего размера, поэтому, когда php-код выводит все буферы чанков на той же странице, сервер перехватывает больший файл. Поэтому я хотел обновить страницу буфера 3.999mb на 3.999mb. Каждый раз, когда будет загружен буфер 3,999 Мб, и я смогу загрузить весь файл путем слияния перед загрузкой фрагмента в новый запрос следующего фрагмента.
Пример:
общий размер файла: 10 МБ, теперь я хочу начать загрузку с первого блока
3.999 МБ, затем автоматически обновляется страница с новым запросом в следующем диапазоне 3.999 МБ, и этот следующий диапазон будет объединяться с первыми 3.999 МБ, а затем автоматически обновляться с новым запросом в следующем
диапазон 2.2mb и объединить его перед загрузкой 7.998mb. Всего скачано
10 МБ (полный файл).
NB. Я не хочу использовать 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;
}
?>
Спасибо