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

使用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 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;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?