为什么在使用 HTTP Accept-Ranges 提供大文件时未满足 PHP

以下脚本用于(评估)向客户端发送大型视频文件。它在后面使用http headers Accept-Ranges。即使在处理大文件(> 2 GB)时,也不会满足 PHP 限制(为了测试,我设置了较小的值,例如 memory_limit=16MB 和 max_execution_time=30)。

我想“理解”后面的上下文,因为 chrome 仅显示一个(部分)请求,每隔几秒增加“时间”和“大小”,尽管 apache 日志文件中没有显示其他请求。

$file = './videos/' . basename($_GET['video']);


if(!file_exists($file)) return; 


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

$size   = filesize($file); // File size 

$length = $size;           // Content length

$start  = 0;               // Start byte

$end    = $size - 1;       // End byte  


header('Content-type: video/mp4');

header("Accept-Ranges: 0-$length");

header("Accept-Ranges: bytes"); 


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

}   



拉丁的传说
浏览 83回答 1
1回答

素胚勾勒不出你

curl通过在不使用任何范围标头的情况下通过命令行请求脚本,同时拥有max_execution_time=1并提供 2.893 GB 文件,找出了更多详细信息。在同一台机器上(在 7 秒和 678 MB 处中止):% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed  23 2893M   23  678M    0     0  92.5M      0  0:00:31  0:00:07  0:00:24     0 curl: (18) transfer closed with 2322893144 bytes remaining to read在带宽较低的外国机器上(在 49 秒和 599 MB 处中止):% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed  20 2893M   20  599M    0     0  12.1M      0  0:03:58  0:00:49  0:03:09 10284 curl: (18) transfer closed with 2404747608 bytes remaining to read就此而言,amax_execution_time=30在这种情况下并不是真正的“小”,因为它允许传输估计约 30 * 600 MB(= 18 GB!)。客户端的请求持续时间与服务器端的执行时间完全无关。事实上,当从 html5 视频对象中调用脚本时,会完成多个部分请求max_execution_time=1(在带宽更低的桌面客户端上,每个请求大约需要 14 分钟,直到中止并传输大约 500 MB)。最后,我很困惑,因为客户端请求持续时间和服务器端执行时间之间存在巨大差异。
打开App,查看更多内容
随时随地看视频慕课网APP