强制下载在中间失败

时间:2018-03-08 19:52:41

标签: php

我在PHP中创建了一个脚本来下载 public_html 之外的文件(出于安全考虑),为此我使用了以下脚本:

<?php
if(condition){
    set_time_limit(60 * 5);
    ini_set('max_execution_time', 60 * 5);
    $path = "path/to/files";
    $fd = fopen($path, "rb");
    if ($fd) {
        $fsize = filesize($path);
        header("Content-type: application/zip");
        header("Content-Disposition: attachment; filename=OCTOPUS_3.1.zip");
        header("Content-length: $fsize");
        header("Cache-control: private"); //use this to open files directly
        while(!feof($fd)) {
            $buffer = fread($fd, 1*(1024*1024));
            echo $buffer;
            ob_flush();
            flush();    //These two flush commands seem to have helped with performance
        }
    }
    else {
        echo "Error opening file";
    }
    fclose($fd);
}

&GT;

但是当我尝试下载文件时,它总是在下载过程中停止。我已经搜索了很多处理大文件的方法,但它们都已经在上面的代码中实现了。

编辑1: 刚到家,我有一个更快的互联网连接,下载工作正常。 但是当我尝试以大约100-200 kbps的速度下载时,下载总是在中间停止。 尝试使用:

header("Transfer-Encoding: chunked", true);
header("Content-Encoding: chunked", true);
header("Content-Type: application/zip", true);
header("Connection: keep-alive", true);

但即使在快速连接上它也没有用,它说:失败。网络问题

还补充说:

set_time_limit(60 * 200);
ini_set('max_execution_time', 60 * 200);

它也不起作用。

2 个答案:

答案 0 :(得分:0)

您可以尝试发送chunked transfer response

示例:

<?php

set_time_limit(60 * 5);
ini_set('max_execution_time', 60 * 5);

$fileName = __DIR__ . '/file.zip';
$baseName = basename($fileName);
$fileSize = filesize($fileName);
$file = fopen($fileName, 'r');

header("Transfer-Encoding: chunked", true);
header("Content-Encoding: chunked", true);
header("Content-Type: application/zip", true);
header("Content-Disposition: attachment; filename=$baseName");
header("Connection: keep-alive", true);
header("Content-length: $fileSize");

while (($buffer = fgets($file, 4096)) !== false) {
    ob_start();
    echo sprintf("%x\r\n%s\r\n", strlen($buffer), $buffer);
    ob_end_flush();
}

fclose($file);

答案 1 :(得分:0)

也许PHP脚本超时了。您应该尝试为脚本设置适当的time limit

虽然不能保证始终可以正常工作:在执行下载的php文件/函数顶部添加以下内容: set_time_limit(0)

然后,如果它可以将时间限制值调整为允许在慢速连接下进行下载的内容,例如600(10分钟)

虽然这不是灵丹妙药,但连接速度很慢或不稳定的用户可能仍然无法获得拉链。