Загрузки Resumable, чтобы использование PHP отправило файл?

typedef typename Tail::inUnion dummy;

Однако я не уверен, что реализация inUnion верна. Если я правильно понимаю, этот класс не должен быть создан, поэтому вкладка «fail» никогда не будет автоматически терпеть неудачу. Возможно, было бы лучше указать, находится ли тип в объединении или нет с простым булевым значением.

template  struct Contains;

template 
struct Contains >
{
    enum { result = Contains::result };
};

template 
struct Contains >
{
    enum { result = true };
};

template 
struct Contains
{
    enum { result = false };
};

PS: Посмотрите на Boost :: Variant

PS2: посмотрите на typelists , особенно в книге Андрея Александреску: Modern C ++ Design

101
задан Mark Amery 10 January 2016 в 14:32
поделиться

5 ответов

Да. Поддержка byteranges. Посмотрите раздел RFC 2616 14.35 .

Это в основном означает, что необходимо читать Range заголовок и начать служить файлу от указанного смещения.

Это означает, что Вы не можете использовать readfile (), так как это служит целому файлу. Вместо этого используйте fopen () первый, тогда fseek () к правильному положению, и затем используйте fpassthru () для обслуживания файла.

15
ответ дан Sietse 24 November 2019 в 04:39
поделиться

Да, можно использовать заголовок Диапазона для этого. Необходимо дать еще 3 заголовка клиенту для полной загрузки:

header ("Accept-Ranges: bytes");
header ("Content-Length: " . $fileSize);
header ("Content-Range: bytes 0-" . $fileSize - 1 . "/" . $fileSize . ";");

, Чем для прерванной загрузки необходимо проверить заголовок запроса Диапазона:

$headers = getAllHeaders ();
$range = substr ($headers['Range'], '6');

И в этом случае не забывают служить содержанию с 206 кодами статуса:

header ("HTTP/1.1 206 Partial content");
header ("Accept-Ranges: bytes");
header ("Content-Length: " . $remaining_length);
header ("Content-Range: bytes " . $start . "-" . $to . "/" . $fileSize . ";");

Вы будете получать переменные $start и $to из заголовка запроса и использовать fseek () для поиска на правильное положение в файле.

2
ответ дан Zsolt Szeberenyi 24 November 2019 в 04:39
поделиться

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

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

1
ответ дан Mike Dimmick 24 November 2019 в 04:39
поделиться

Первая вещь, которую необходимо сделать, состоит в том, чтобы отправить Accept-Ranges: bytes заголовок во всех ответах, чтобы сказать клиенту, что Вы поддерживаете частичное содержание. Затем если запрос с a Range: bytes=x-y заголовок получен (с x и y будучи числами) Вы анализируете диапазон, который запрашивает клиент, откройте файл, как обычно, ищите x байты вперед и отправляют следующее y - x байты. Также установите ответ на HTTP/1.0 206 Partial Content.

Не протестировав что-либо, это могло работать, более или менее:

$filesize = filesize($file);

$offset = 0;
$length = $filesize;

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

    $partialContent = true;

    // find the requested range
    // this might be too simplistic, apparently the client can request
    // multiple ranges, which can become pretty complex, so ignore it for now
    preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);

    $offset = intval($matches[1]);
    $length = intval($matches[2]) - $offset;
} else {
    $partialContent = false;
}

$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');

    header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $filesize);
}

// output the regular HTTP headers
header('Content-Type: ' . $ctype);
header('Content-Length: ' . $filesize);
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Accept-Ranges: bytes');

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

Я, возможно, пропустил что-то очевидное, и я совершенно определенно проигнорировал некоторые потенциальные источники ошибок, но это должен быть запуск.

Существует описание частичного содержания здесь, и я нашел некоторую информацию о частичном содержании на странице документации для освобожденного.

100
ответ дан Theo 24 November 2019 в 04:39
поделиться

Действительно хороший способ решить эту проблему без необходимости «катить свой собственный» PHP-код - это использовать модуль Apache mod_xsendfile. Затем в PHP вы просто устанавливаете соответствующие заголовки. Apache делает свое дело.

header("X-Sendfile: /path/to/file");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; file=\"filename\"");
11
ответ дан 24 November 2019 в 04:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: