PHP远程文件流与恢复支持
发布时间:2020-07-22 21:15:32 所属栏目:PHP 来源:互联网
导读:首先,我知道以前有类似的问题. 这个问题几乎解释了这个问题,但是, 该文件托管在另一台服务器上,用户将通过我的脚本下载文件,流式传输给他… 但是问题是用户无法恢复一次暂停…任何解决方案? 您可以尝试使用Accept-Ranges和Content-Range实现自己的下载脚本,
|
首先,我知道以前有类似的问题. 这个问题几乎解释了这个问题,但是, 该文件托管在另一台服务器上,用户将通过我的脚本下载文件,流式传输给他… 但是问题是用户无法恢复一次暂停…任何解决方案? 您可以尝试使用Accept-Ranges和Content-Range实现自己的下载脚本,这里是一个概念:set_time_limit(0);
$download = new ResumeDownload("word.dir.txt",50000); //delay about in microsecs
$download->process();
使用Internet下载管理器 开始 已暂停 暂停状态 恢复 成品 使用类 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",$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-streamrn";
$formatRange = "Content-range: bytes %d-%d/%drnrn";
foreach ( $ranges as $range ) {
$this->getRange($range,$end);
$length += strlen("rn--$this->boundaryrn");
$length += strlen($tl);
$length += strlen(sprintf($formatRange,$this->size));
$length += $end - $start + 1;
}
$length += strlen("rn--$this->boundary--rn");
header("Content-Length: $length");
header("Content-Type: multipart/x-byteranges; boundary=$this->boundary");
foreach ( $ranges as $range ) {
$this->getRange($range,$end);
echo "rn--$this->boundaryrn";
echo $tl;
echo sprintf($formatRange,$this->size);
fseek($this->file,$start);
$this->readBuffer($end - $start + 1);
}
echo "rn--$this->boundary--rn";
}
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);
}
}
}
File Used (编辑:鄂州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
