使用readfile()无法下载大文件

时间:2016-01-10 12:32:19

标签: php download

我有以下代码强制下载IPA文件(在用脚本对其进行编码后)。它适用于较小的文件,但文件较大,我的Web服务器开始返回500内部服务器错误。有人能够帮助我调整现有代码来克服这个问题吗?

$time = md5(time());

// Runs code signing script here
// And then attempts to initiate download

$path = "done/$time/";         
$latest_ctime = 0;
$latest_filename = '';    

$d = dir($path);
while (false !== ($entry = $d->read())) {
  $filepath = "{$path}/{$entry}";
  if (is_file($filepath) && filectime($filepath) > $latest_ctime) {
    $latest_ctime = filectime($filepath);
    $latest_filename = $entry;
  }
}        

 header("Cache-Control: public");
 header("Content-Description: File Transfer");
 header("Content-Disposition: attachment; filename=$time.ipa");
 header("Content-Type: application/ipa");
 header("Content-Transfer-Encoding: binary");
 // Read the file from disk
 readfile("done/$time/".$latest_filename);
       // header('location: dashboard.php');
   } else {
// Throwback

die("Failed. Contact support. // <p>$sign</p>");

}

2 个答案:

答案 0 :(得分:1)

以下是一个例子:

$filepath = "done/{$time}/{$latest_filename}";
$size     = filesize($filepath);
$mimetype = 'application/ipa';

// Turn off buffering
if (ob_get_level()) {
    ob_end_clean();
}

$handle = fopen($filepath, 'rb');
if ($handle !== false && $size > 0) {
    @flock($handle, LOCK_SH);

    $filename               = rawurldecode($filepath);
    $old_max_execution_time = ini_get('max_execution_time');
    $old_cache_limiter      = session_cache_limiter();

    ini_set('max_execution_time', 0);
    session_cache_limiter(false);

    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header('Content-Type: ' . $mimetype);
    header('Content-Transfer-Encoding: binary');
    header('Content-disposition: attachment; filename="'. $filename .'"');
    // or your variant
    // header("Content-Disposition: attachment; filename=" . md5(time()));

    header("Content-Length: $size");

    $start = 0;
    $end   = $size - 1;
    $chunk = 8 * 1024;

    $requested  = (float)$end - (float)$start + 1;

    while (! $error) {
        if ($chunk >= $requested) {
            $chunk = (integer)$requested;
        }

        set_time_limit(0);

        while (! feof($handle) && (connection_status() === 0)) {
            if (! $buffer = @fread($handle, $chunk)) {
                $error = true;
                break 2;
            }

            print($buffer);
            flush();
        }

        @flock($handle, LOCK_UN);
        @fclose($handle);

        ini_set('max_execution_time', $old_max_execution_time);
        session_cache_limiter($old_cache_limiter);
        break;
    }

    if ($error) {
        // 500 - Internal server error
        exit;
    }
} else {
    // Can't open file
    exit;
}

答案 1 :(得分:0)

脚本时间执行可能有问题。 尝试设置ini_set('max_execution_time', 0); 还尝试按块读取和发送文件。