2015-07-22 2 views
0

Я использую этот скрипт для загрузки файлов на php.
Here - это исходный источник, где я копировал сценарий.загрузка php завершается с ошибкой в ​​середине загрузки

if(file_exists($path)){ 
     $file_size = filesize($path); 
     $file = fopen($path,"rb"); 
     $chunksize = 2*1024*1024; // how many bytes per chunk 
     if($file){ 
      header("Content-Description: File Transfer"); 
      header("Pragma: public"); 
      header("Expires: 0"); 
      header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0"); 
      header("Content-Disposition: attachment; filename=\"$name.$format\""); 
      header("Content-Type: $mimetype"); 

      //check if http_range is sent by browser (or download manager) 
      if(isset($_SERVER['HTTP_RANGE'])){ 
       list($size_unit, $range_orig) = explode('=', $_SERVER['HTTP_RANGE'], 2); 
       if ($size_unit == 'bytes'){ 
        //multiple ranges could be specified at the same time, but for simplicity only serve the first range 
        //http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt 
        list($range, $extra_ranges) = explode(',', $range_orig, 2); 
       } 
       else{ 
        $range = ''; 
        header('HTTP/1.1 416 Requested Range Not Satisfiable'); 
        exit; 
       } 
      } 
      else{ 
       $range = ''; 
      } 

      //figure out download piece from range (if set) 
      list($seek_start, $seek_end) = explode('-', $range, 2); 

      //set start and end based on range (if set), else set defaults 
      //also check for invalid ranges. 
      $seek_end = (empty($seek_end)) ? ($file_size - 1) : min(abs(intval($seek_end)),($file_size - 1)); 
      $seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0); 

      //Only send partial content header if downloading a piece of the file (IE workaround) 
      if ($seek_start > 0 || $seek_end < ($file_size - 1)){ 
       header('HTTP/1.1 206 Partial Content'); 
       header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$file_size); 
       header('Content-Length: '.($seek_end - $seek_start + 1)); 
      } 
      else 
       header("Content-Length: $file_size"); 

      header('Accept-Ranges: bytes'); 

      set_time_limit(0); 
      @fseek($file, $seek_start); 

      while(!feof($file)){ 
       print(@fread($file, $chunksize)); 
       ob_flush(); 
       flush(); 
       if (connection_status()!=0){ 
        @fclose($file); 
        exit; 
       } 
      } 
      @fclose($file); 
      exit; 
     } 
     else{ 
      // file couldn't be opened 
      header("HTTP/1.0 500 Internal Server Error"); 
      exit; 
     } 
    } 
    else { 
     // file does not exist 
     header("HTTP/1.0 404 Not Found"); 
     exit; 
    } 

Теперь проблема.
Загрузка больших файлов (e, g> 20MB) иногда скачивается успешно. и иногда он ломается в середине загрузки. например, я протестировал и выяснил, что для 100 МБ-файла после загрузки 40 МБ это не удалось. (не один раз, несколько раз.)
В браузере, похоже, что файл установлен полностью. (Firefox и хром не содержали Failed text в панели загрузки, но существует опция «open contains folder»)
Некоторые из моих друзей с очень медленным подключением к Интернету говорят, что с ним была проблема с меньшими файлами (менее 1 МБ). но я никогда не испытывал этого. (возможно, потому что мой интернет не медленный)
Так что проблема в том, что когда кто-то с медленным подключением хочет скачать, посередине он ломается для него. (Я предполагаю, что сервер не отправляет файл на него больше.)
Note1: У меня есть эти два заголовка тоже:

Connection: Keep-Alive 
Keep-Alive: timeout=5 

И это пример загрузки файла для тех, кто хочет проверить: https://goo.gl/9flVng
Еще один вопрос: не лучше ли отправлять пользователю файл с header: location вместо readfile(), fread(), ...?

Извините за длинный вопрос, спасибо за помощь.

+0

Возможно, стоит посмотреть в cdn как другой вариант – Adam

+0

да, cdn - хорошая идея. Я еще не испытал этого, кажется, я должен проверить его некоторое время. но о текущей проблеме, мой сервер хороший. не должно быть никаких проблем. Любая идея о скрипте или конфигурации сервера? Я просто знаю, что соединение между клиентом и сервером отказывается и не пересоединяется. Почему браузер не отображает «неудачный» текст? – Saeed

ответ

0

Вы можете попытаться увеличить максимальное время выполнения сценария, по умолчанию оно установлено в 30 секунд. Установка его на 0 удаляет ограничение по времени.

set_time_limit (0) 
+0

Спасибо, Луис за помощь. Да, я сделал это уже. вы можете увидеть это в коде, который я предоставил. но никакого положительного результата. любая другая помощь? Я предполагаю, что проблема связана с сервером или чем-то, связанным с ним, а не с скриптом. Есть идеи? – Saeed

Смежные вопросы