在 PHP 中可靠地下载大文件

2022-08-30 15:39:41

我在服务器上有一个php脚本,用于将文件发送给食谱:他们获得一个唯一的链接,然后他们可以下载大文件。有时传输出现问题,文件已损坏或永远无法完成。我想知道是否有更好的方法来发送大文件

法典:

$f = fopen(DOWNLOAD_DIR.$database[$_REQUEST['fid']]['filePath'], 'r');
while(!feof($f)){
    print fgets($f, 1024);
}
fclose($f);

我见过这样的功能:

http_send_file
http_send_data

但我不确定它们是否会起作用。

解决此问题的最佳方法是什么?

问候


答案 1

分块文件是PHP中最快/最简单的方法,如果你不能或不想使用更专业的东西,如cURLApache上的mod-xsendfile或一些专用脚本

$filename = $filePath.$filename;

$chunksize = 5 * (1024 * 1024); //5 MB (= 5 242 880 bytes) per one chunk of file.

if(file_exists($filename))
{
    set_time_limit(300);

    $size = intval(sprintf("%u", filesize($filename)));

    header('Content-Type: application/octet-stream');
    header('Content-Transfer-Encoding: binary');
    header('Content-Length: '.$size);
    header('Content-Disposition: attachment;filename="'.basename($filename).'"');

    if($size > $chunksize)
    { 
        $handle = fopen($filename, 'rb'); 

        while (!feof($handle))
        { 
          print(@fread($handle, $chunksize));

          ob_flush();
          flush();
        } 

        fclose($handle); 
    }
    else readfile($path);

    exit;
}
else echo 'File "'.$filename.'" does not exist!';

richnetapps.com/ NeedBee移植。在 200 MB 的文件中进行了测试,这些文件已失效,即使允许的最大内存限制设置为 ,也比下载的文件大小大五倍。readfile()1G

顺便说一句:我也在文件上测试了这一点,但是PHP只设法首先写入文件,然后断开了连接。与文件相关的函数(fopen、fread、fseek)使用 INT,因此您最终达到了 .上面提到的解决方案(即)似乎是在这种情况下唯一的选择。>2GB2GB2GBmod-xsendfile

编辑让自己100%的文件保存在utf-8中。如果省略它,下载的文件将损坏。这是因为此解决方案使用打印将文件块推送到浏览器。


答案 2

如果要发送真正大的文件并担心这将产生的影响,则可以使用 x-sendfile 标头。

从 SOQ using-xsendfile-with-apache-php,一个 howto blog.adaniels.nl: how-i-php-x-sendfile/


推荐