0

我正在为我目前正在处理的一个更大的项目构建一个小型下载模块,并且遇到了一些问题。尽管它非常适合小文件,但当浏览器(任何浏览器)开始下载较大的文件时,它会像任何页面一样简单地加载,然后在最后几秒钟内几乎立即“下载”整个文件(无论大小)。我一遍又一遍地浏览了 HTTP 1.1 标准,并且似乎一直在遵循它们。立即想到的一个想法是 PHP 实际上是在向客户端发送数据的时候。答案应该是脚本运行时 - 我在其他长脚本中使用此原理进行调试。

这是相关的代码(当然还有更多,但这是实际发送标头和输出的地方:

header("Content-Type: application/force-download");
header("Content-length: $size");
header('Content-Disposition: attachment; filename="'.$fileData['name'].'"');    
for ($i=0; $i<$size; $i+=$step)
{
    $content = fread($file, $step);
    if ($content === false)
        $content = "";

    echo $content;
}
die();

有任何想法吗?我有一种感觉,这是一个明显的问题,我长时间盯着这个街区看不到。

提前致谢!

4

2 回答 2

0

在这里试试这个,如果传递的文件是目录或没有找到,这个函数将返回 false。它还将从文件名中删除空格,以免中断下载。它还可以通过更改来限制下载速度,1024它将处理超过 2GB 的文件。

<?php 
function download($file){
    if (file_exists($file)) {
        if(is_dir($file)){return false;}
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.str_ireplace(' ','_',basename($file)).'"');
        header('Content-Transfer-Encoding: binary');
        header('Connection: Keep-Alive');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: '.sprintf("%u", filesize($file)));

        @ob_clean();
        $handle = fopen($file, "rb");
        $chunksize=(sprintf("%u", (filesize($file))/1024));

        set_time_limit(0);
        while (!feof($handle)) {
            echo fgets($handle, $chunksize);
            flush();
        }
        fclose($handle);
        die;
    }else{return false;}
    return;
}
?>
于 2012-06-14T15:59:31.733 回答
0

只需使用工具,停止重新发明轮子。pecl_http已经存在了一段时间了。

<?php
http_send_content_disposition("document.pdf", true);
http_send_content_type("application/pdf");
http_throttle(0.1, 2048);
http_send_file("../report.pdf");
?>

此代码示例快速、健壮,它为您提供多种功能奖励:

  • 带宽限制
  • 缓存和标头管理
  • 部分和可恢复下载
于 2012-06-14T16:09:37.257 回答