用php下载大文件

时间:2010-12-28 18:36:51

标签: php

我必须编写一个php脚本来下载潜在的大文件。我在这里报告的文件大部分时间都可以正常工作。但是,如果客户端的连接速度很慢,则请求在下载过程中结束(状态代码为200),但并不总是在同一点,而不是在同一时间。我试图覆盖一些php.ini变量(参见第一个语句),但问题仍然存在。 我不知道它是否相关,但我的托管服务器是SiteGround,对于简单的静态文件请求,下载工作正常,连接速度慢。

我找到了Forced downloading large file with php,但我不明白马里奥的回答。我是网络编程的新手。

所以这是我的代码。

    <?php
    ini_set('memory_limit','16M');
    ini_set('post_max_size', '30M');
    set_time_limit(0);

    include ('../private/database_connection.php');


    $downloadFolder = '../download/';
    $fileName = $_POST['file'];
    $filePath = $downloadFolder . $fileName;
    if($fileName == NULL)
    {
        exit;
    }
    ob_start();
    session_start();


    if(!isset($_SESSION['Username']))
    {
        // or redirect to login (remembering this download request)
        $_SESSION['previousPage'] = 'download.php?file=' . $fileName;
        header("Location: login.php");
        exit;
    }

    if (file_exists($filePath))
    {               
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        //header('Content-Disposition: attachment; filename='.$fileName);
        header("Content-Disposition: attachment; filename=\"$fileName\"");
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        //header('Pragma: public');
        header('Content-Length: ' . filesize($filePath));
        ob_clean();
        flush();

        // download
        // 1
//      readfile($filePath);
        // 2
        $file = @fopen($filePath,"rb");
        if ($file) {
          while(!feof($file)) {
            print(fread($file, 1024*8));
            flush();
            if (connection_status()!=0) {
              @fclose($file);
              die();
            }
          }
          @fclose($file);
        }
        exit;
    }
    else
    {
        header('HTTP/1.1 404 File not found');
        exit;
    }
?>

1 个答案:

答案 0 :(得分:2)

HTTP状态代码200表示一切正常。

检查您的Content-Length是否正确,并尝试不使用connection_status()函数。可能是报告用户断开连接不正确。 PHP具有connection_aborted()功能,可能就是您所需要的。

更新:因为您询问了Mario的答案,他的意思是您应该将用户重定向到服务器上的实际文件并让服务器处理它而不是尝试复制服务器的内容已经可以做了。换句话说,您应该使用header("Location: " . $filePath)或文件路径的链接,而不是使用您的脚本。缺点是您无法使用附件样式下载,但您可以在新窗口中打开它,这将产生类似的效果。