用php强制下载大文件

时间:2010-12-13 01:41:23

标签: php download

我网站的许多用户报告说下载大文件(80 MB)时出现问题。我正在使用标头强制下载。如有必要,我可以提供额外的PHP设置。我正在使用CakePHP框架,但这段代码都是常规的php。我正在使用php 5.2 with apache在来自media temple,CentOS Linux的专用虚拟服务器上。您是否看到以下代码存在任何问题:

        set_time_limit(1500);
        header("Content-Type: application/octet-stream");
        header("Content-Disposition: attachment; filename=\"" . basename($file_path) . "\"");
        header("Content-Length: ".$content_length);
        header("Content-Transfer-Encoding: binary");
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Cache-Control: private', false);
        header('Pragma: public');
        header('Expires: 0');

        //Change this part
        $handle = fopen($file_path, 'rb');
        while (!feof($handle))
        {
            echo fread($handle, 4096);
            ob_flush();
            flush();
        }
        fclose($handle);
        exit;

基本上,报告的问题是下载开始然后在中间停止。我认为这是时间限制的问题,所以我添加了set_time_limit代码。我之前使用的是php readfile函数,但是也没有顺利运行。

2 个答案:

答案 0 :(得分:4)

PHP发起的http传输的问题在于它们很少支持部分请求:

GET /yourfile HTTP/1.1
Range: bytes=31489531-79837582

每当浏览器遇到传输问题时,它都会尝试恢复下载。你的PHP脚本不适合它(它不是微不足道的,所以没有人这样做。)

所以真的避免这种情况。将用户重定向到静态文件并让您的Web服务器处理它。如果您需要处理授权,请使用检查会话cookie甚至是静态权限文件(./allowed/178.224.2.55-file-1)的符号链接或重写文件等技巧。任何所需的额外HTTP标头都可以同样注入,或者使用.meta文件注入。

答案 1 :(得分:1)

我没有看到任何麻烦,但是对于S& G来说,尝试将set_time_limit放在while循环中。这样可以确保它们不会达到硬限制(只要客户端获取信息),时间限制就会延长。