【问题标题】:php download fails at the middle of downloadphp下载在下载过程中失败
【发布时间】:2015-07-22 07:56:17
【问题描述】:

我使用此脚本下载 php 中的文件。
Here 是我复制脚本的原始来源。

if(file_exists($path)){
        $file_size = filesize($path);
        $file = fopen($path,"rb");
        $chunksize = 2*1024*1024; // how many bytes per chunk
        if($file){
            header("Content-Description: File Transfer");
            header("Pragma: public");
            header("Expires: 0");
            header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
            header("Content-Disposition: attachment; filename=\"$name.$format\"");
            header("Content-Type: $mimetype");

            //check if http_range is sent by browser (or download manager)
            if(isset($_SERVER['HTTP_RANGE'])){
                list($size_unit, $range_orig) = explode('=', $_SERVER['HTTP_RANGE'], 2);
                if ($size_unit == 'bytes'){
                    //multiple ranges could be specified at the same time, but for simplicity only serve the first range
                    //http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
                    list($range, $extra_ranges) = explode(',', $range_orig, 2);
                }
                else{
                    $range = '';
                    header('HTTP/1.1 416 Requested Range Not Satisfiable');
                    exit;
                }
            }
            else{
                $range = '';
            }

            //figure out download piece from range (if set)
            list($seek_start, $seek_end) = explode('-', $range, 2);

            //set start and end based on range (if set), else set defaults
            //also check for invalid ranges.
            $seek_end   = (empty($seek_end)) ? ($file_size - 1) : min(abs(intval($seek_end)),($file_size - 1));
            $seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0);

            //Only send partial content header if downloading a piece of the file (IE workaround)
            if ($seek_start > 0 || $seek_end < ($file_size - 1)){
                header('HTTP/1.1 206 Partial Content');
                header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$file_size);
                header('Content-Length: '.($seek_end - $seek_start + 1));
            }
            else
                header("Content-Length: $file_size");

            header('Accept-Ranges: bytes');

            set_time_limit(0);
            @fseek($file, $seek_start);

            while(!feof($file)){
                print(@fread($file, $chunksize));
                ob_flush();
                flush();
                if (connection_status()!=0){
                    @fclose($file);
                    exit;
                }
            }
            @fclose($file);
            exit;
        }
        else{
            // file couldn't be opened
            header("HTTP/1.0 500 Internal Server Error");
            exit;
        }
    }
    else {
        // file does not exist
        header("HTTP/1.0 404 Not Found");
        exit;
    }

现在,问题来了。
下载大文件(例如 > 20MB)有时会成功完成下载。有时它会在下载过程中中断。例如,我测试并发现对于一个 100MB 的文件,下载 40MB 后它失败了。 (不是一次,是多次。)
在浏览器中,文件似乎已完全下载。 (Firefox 和 chrome 在下载栏中没有“失败”文本。但存在“打开包含文件夹”选项)
我的一些互联网连接速度很慢的朋友说,对于较小的文件(小于 1 MB),他也遇到了同样的问题。但我从来没有经历过。 (可能是因为我的网速不慢)
所以问题是,当连接速度较慢的人想要下载时,在中间,它会为他中断。 (我猜服务器不再向他发送文件了。)
注意1:我也有这两个标题:

Connection: Keep-Alive
Keep-Alive: timeout=5

这是一个示例下载文件,供任何想要测试它的人使用: https://goo.gl/9flVng
再问一个问题,直接让用户用header: location而不是readfile(), fread(), ...下载文件不是更好吗?

抱歉,问题很长,感谢您的帮助。

【问题讨论】:

  • 可能值得研究 CDN 作为另一种选择
  • 是的,cdn 是个好主意。我还没有体验过,看来我应该测试一下。但是关于当前的问题,我的服务器是一个很好的。应该没有问题。关于脚本或服务器配置的任何想法?我只知道客户端和服务器之间的连接拒绝并且不会重新连接。为什么浏览器不显示“失败”文本??

标签: php download


【解决方案1】:

您可以尝试提高脚本的最大执行时间限制,默认设置为 30 秒。将其设置为 0 会删除时间限制。

set_time_limit (0)

【讨论】:

  • 感谢路易斯的帮助。是的,我已经做到了。你可以在我提供的代码中看到它。但没有积极的结果。还有其他帮助吗?我想问题出在服务器或与之相关的东西上,而不是脚本上。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-31
  • 1970-01-01
  • 2020-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多