传输大于500mb的文件

时间:2014-07-07 15:42:01

标签: php http

我用php创建了一个文件,可以在服务器中流式传输文件,但我唯一的问题是简历,我只能用1个并行使用IDM下载我一直在搜索一周没有找到任何帮助这是我的代码

    <?php
$file = 'http://www.affymetrix.com/support/downloads/demo_data/Demo_Data_Barley_MAS5.zip';


function get_size($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_exec($ch);
    $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
    return intval($size);
}


$fp = @fopen($file, 'rb');

$size   = get_size($file); // File size
$length = $size;           // Content length
$start  = 0;               // Start byte
$end    = $size - 1;       // End byte
header('Content-Type: application/octet-stream');
 header("Content-Disposition: attachment; filename=Demo_Data_Barley_MAS5.zip");
//header('Content-type: video/mp4');
header("Accept-Ranges: 0-$length");
if (isset($_SERVER['HTTP_RANGE'])) {

    $c_start = $start;
    $c_end   = $end;

    list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
    if (strpos($range, ',') !== false) {
        header('HTTP/1.1 416 Requested Range Not Satisfiable');
        header("Content-Range: bytes $start-$end/$size");
        exit;
    }
    if ($range == '-') {
        $c_start = $size - substr($range, 1);
    }else{
        $range  = explode('-', $range);
        $c_start = $range[0];
        $c_end   = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
    }
    $c_end = ($c_end > $end) ? $end : $c_end;
    if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
        header('HTTP/1.1 416 Requested Range Not Satisfiable');
        header("Content-Range: bytes $start-$end/$size");
        exit;
    }
    $start  = $c_start;
    $end    = $c_end;
    $length = $end - $start + 1;
    fseek($fp, $start);
    header('HTTP/1.1 206 Partial Content');
}
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: ".$length);


$buffer = 1024 * 8;
while(!feof($fp) && ($p = ftell($fp)) <= $end) {

    if ($p + $buffer > $end) {
        $buffer = $end - $p + 1;
    }
    set_time_limit(0);
    echo fread($fp, $buffer);
    flush();
}

fclose($fp);
exit();
?>

如果有人可以帮助我,我真的非常感谢

1 个答案:

答案 0 :(得分:0)

使用以下gist源代码:https://gist.github.com/kijin/9735300 (对不起由韩语注释的链接的要点源代码)

标题的翻译:

supports:
 1. do not break filename when use UTF-8 filename.
 2. remove or replace if included unknown character by OS.
 3. Add Cache-Control, Expires header when you want to use cache.
 4. Fix the download error when use cache and IE <= 8.
 5. Support resume download (automatically detect Range header, auto generate Accept-Ranges header)
 6. Fix memory leak when download large file.
 7. Can limit download speed.

How to use: send_attachment('filename that provide to client', 'file path', [period of the caching], [speed limit]);

this example is download 'foo.jpg' from server to client named 'photo.jpg'
 send_attachment('photo.jpg', '/srv/www/files/uploads/foo.jpg')

Return: true when successfully sent else false.

Warning: 1. please execute 'exit' when end the transfer.
         2. don't ensure that php version is very low(< 5.1) or not UTF-8 environment.
         3. speed limitation is very dangerous when you using FastCGI/FPM. recommend to use web server's speed limitation.
         4. some android versions does not support UTF-8 encoding.

注意:我建议在传输大文件时使用X-Accel-Redirect(nginx)或X-Sendfile(apache)标头。如果你在php解释器上传输大文件,那么php会有很多负载而且工作效率非常低。

添加:这是您要执行的代码 - https://gist.github.com/ssut/a3d97c7a35e5458687ed (注意:我的英语很差,有些翻译不精确)

我在nginx + php 5.5(fpm)环境中测试了这段代码,这是测试代码:send_attachment('ubuntu.iso', 'http://ftp.daum.net/ubuntu-releases/trusty/ubuntu-14.04-server-amd64.iso');

IDM截图: