Возобновляемая загрузка при использовании PHP для отправки файла? - PullRequest
100 голосов
/ 01 октября 2008

Мы используем сценарии PHP для туннелирования загрузки файлов, поскольку мы не хотим указывать абсолютный путь к загружаемому файлу:

header("Content-Type: $ctype");
header("Content-Length: " . filesize($file));
header("Content-Disposition: attachment; filename=\"$fileName\"");
readfile($file);

К сожалению, мы заметили, что загрузка, проходящая через этот скрипт, не может быть возобновлена ​​конечным пользователем.

Есть ли способ поддержать возобновляемую загрузку с помощью такого решения на основе PHP?

Ответы [ 13 ]

1 голос
/ 14 марта 2011

Спасибо Тео! Ваш метод не работал напрямую для потоковой передачи DivX, потому что я обнаружил, что DivX Player посылает диапазоны, как байты = 9932800-

но он показал мне, как это сделать, так что спасибо: D

if(isset($_SERVER['HTTP_RANGE']))
{
    file_put_contents('showrange.txt',$_SERVER['HTTP_RANGE']);
1 голос
/ 01 октября 2008

Возобновление загрузки по HTTP осуществляется через заголовок Range. Если запрос содержит заголовок Range и другие индикаторы (например, If-Match, If-Unmodified-Since) указывают на то, что содержимое не изменилось с момента начала загрузки, вы даете код ответа 206 (а не 200), укажите диапазон байтов, который вы возвращаете, в заголовке Content-Range, затем укажите этот диапазон в теле ответа.

Хотя я не знаю, как это сделать в PHP.

0 голосов
/ 03 октября 2017

Вы можете использовать приведенный ниже код для поддержки запроса диапазона байтов в любом браузере

    <?php
$file = 'YouTube360p.mp4';
$fileLoc = $file;
$filesize = filesize($file);
$offset = 0;
$fileLength = $filesize;
$length = $filesize - 1;

if ( isset($_SERVER['HTTP_RANGE']) ) {
    // if the HTTP_RANGE header is set we're dealing with partial content

    $partialContent = true;
    preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);

    $offset = intval($matches[1]);
    $tempLength = intval($matches[2]) - 0;
    if($tempLength != 0)
    {
        $length = $tempLength;
    }
    $fileLength = ($length - $offset) + 1;
} else {
    $partialContent = false;
    $offset = $length;
}

$file = fopen($file, 'r');

// seek to the requested offset, this is 0 if it's not a partial content request
fseek($file, $offset);

$data = fread($file, $length);

fclose($file);

if ( $partialContent ) {
    // output the right headers for partial content
    header('HTTP/1.1 206 Partial Content');
}

// output the regular HTTP headers
header('Content-Type: ' . mime_content_type($fileLoc));
header('Content-Length: ' . $fileLength);
header('Content-Disposition: inline; filename="' . $file . '"');
header('Accept-Ranges: bytes');
header('Content-Range: bytes ' . $offset . '-' . $length . '/' . $filesize);

// don't forget to send the data too
print($data);
?>
...