PHP保护下载管理器

时间:2012-06-14 15:43:03

标签: php http download

我正在为我目前正在处理的大型项目构建一个小型下载模块,并且遇到了一些问题。虽然它适用于小文件,但当浏览器(任何浏览器)开始下载更大的文件时,它只是像任何页面一样加载,然后在最后几秒内“下载”整个文件(无论大小)几乎立即。我一遍又一遍地经历了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();

有什么想法吗?我有一种感觉,这是一个显而易见的问题,我从长时间盯着这个街区看不出来。

提前致谢!

2 个答案:

答案 0 :(得分: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;
}
?>

答案 1 :(得分: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");
?>

此代码示例快速,强大,并为您提供多项功能奖励:

  • 带宽限制
  • 缓存和标头管理
  • 部分和可恢复的下载