PHP Удаленная потоковая передача файлов с поддержкой возобновления

Во-первых, мне известно о том же вопросе, который задавали раньше.

Вопрос в значительной степени объясняет вопрос, но все же,

файл размещается на другом сервере, пользователь загружает файл через мой скрипт, передается ему …

Но проблема в том, что пользователь не может возобновить его после приостановки … любых решений?

Solutions Collecting From Web of "PHP Удаленная потоковая передача файлов с поддержкой возобновления"

Вы можете попробовать реализовать свой собственный сценарий загрузки, используя Accept-Ranges и Content-Range здесь есть понятие профессионала:

 set_time_limit(0); $download = new ResumeDownload("word.dir.txt", 50000); //delay about in microsecs $download->process(); 

Использование Internet Download Manager

Начало

Начало

Приостановлена

Приостановлена

Приостановленное состояние

Приостановленное состояние

Продолжить

Продолжить

Законченный

введите описание изображения здесь

Используемый класс

 class ResumeDownload { private $file; private $name; private $boundary; private $delay = 0; private $size = 0; function __construct($file, $delay = 0) { if (! is_file($file)) { header("HTTP/1.1 400 Invalid Request"); die("<h3>File Not Found</h3>"); } $this->size = filesize($file); $this->file = fopen($file, "r"); $this->boundary = md5($file); $this->delay = $delay; $this->name = basename($file); } public function process() { $ranges = NULL; $t = 0; if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_SERVER['HTTP_RANGE']) && $range = stristr(trim($_SERVER['HTTP_RANGE']), 'bytes=')) { $range = substr($range, 6); $ranges = explode(',', $range); $t = count($ranges); } header("Accept-Ranges: bytes"); header("Content-Type: application/octet-stream"); header("Content-Transfer-Encoding: binary"); header(sprintf('Content-Disposition: attachment; filename="%s"', $this->name)); if ($t > 0) { header("HTTP/1.1 206 Partial content"); $t === 1 ? $this->pushSingle($range) : $this->pushMulti($ranges); } else { header("Content-Length: " . $this->size); $this->readFile(); } flush(); } private function pushSingle($range) { $start = $end = 0; $this->getRange($range, $start, $end); header("Content-Length: " . ($end - $start + 1)); header(sprintf("Content-Range: bytes %d-%d/%d", $start, $end, $this->size)); fseek($this->file, $start); $this->readBuffer($end - $start + 1); $this->readFile(); } private function pushMulti($ranges) { $length = $start = $end = 0; $output = ""; $tl = "Content-type: application/octet-stream\r\n"; $formatRange = "Content-range: bytes %d-%d/%d\r\n\r\n"; foreach ( $ranges as $range ) { $this->getRange($range, $start, $end); $length += strlen("\r\n--$this->boundary\r\n"); $length += strlen($tl); $length += strlen(sprintf($formatRange, $start, $end, $this->size)); $length += $end - $start + 1; } $length += strlen("\r\n--$this->boundary--\r\n"); header("Content-Length: $length"); header("Content-Type: multipart/x-byteranges; boundary=$this->boundary"); foreach ( $ranges as $range ) { $this->getRange($range, $start, $end); echo "\r\n--$this->boundary\r\n"; echo $tl; echo sprintf($formatRange, $start, $end, $this->size); fseek($this->file, $start); $this->readBuffer($end - $start + 1); } echo "\r\n--$this->boundary--\r\n"; } private function getRange($range, &$start, &$end) { list($start, $end) = explode('-', $range); $fileSize = $this->size; if ($start == '') { $tmp = $end; $end = $fileSize - 1; $start = $fileSize - $tmp; if ($start < 0) $start = 0; } else { if ($end == '' || $end > $fileSize - 1) $end = $fileSize - 1; } if ($start > $end) { header("Status: 416 Requested range not satisfiable"); header("Content-Range: */" . $fileSize); exit(); } return array( $start, $end ); } private function readFile() { while ( ! feof($this->file) ) { echo fgets($this->file); flush(); usleep($this->delay); } } private function readBuffer($bytes, $size = 1024) { $bytesLeft = $bytes; while ( $bytesLeft > 0 && ! feof($this->file) ) { $bytesLeft > $size ? $bytesRead = $size : $bytesRead = $bytesLeft; $bytesLeft -= $bytesRead; echo fread($this->file, $bytesRead); flush(); usleep($this->delay); } } } 

Используемый файл

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

Вам нужно будет отправить Accept-Ranges и соответствующим образом отрегулировать диапазоны .

Это кусок работы. Может быть проще использовать mod_proxy .

Какова цель этого? скрывать только URL-адреса или просто разрешать пользователям загружаться?

То, как вы это описали, немного сложно.

  1. Удаленный сервер, на который будет загружен ваш сценарий, должен поддерживать возобновление загрузки.
  2. Ваш php-скрипт должен проверить заголовок «Accept-Range» и передать его на удаленный сервер (используя сокеты – это ваш лучший вариант, я думаю), поэтому ваш скрипт фактически действует как прокси-сервер.