douzhuan1467
douzhuan1467
2016-01-10 12:32
浏览 52
已采纳

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

I have the following code to force download an IPA file (after codesigning it with a script). It works fine with smaller files but with larger files, my web server starts returning a 500 Internal Server Error. Would someone be able to help me tweak my existing code to overcome this issue?

$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条回答 默认 最新

  • doujing4555
    doujing4555 2016-01-10 13:10
    已采纳

    Here is an example:

    $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;
    }
    
    点赞 评论
  • dongwan0574
    dongwan0574 2016-01-10 12:41

    Maybe problem in script time execution. Try to set ini_set('max_execution_time', 0); Also try to read and send file by chunks.

    点赞 评论

相关推荐