За последние 24 часа нас посетили 6929 программистов и 452 робота. Сейчас ищут 183 программиста ...

Как отдать файл на загрузку

Тема в разделе "PHP для новичков", создана пользователем 440Hz, 13 дек 2007.

  1. 440Hz

    440Hz Активный пользователь
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    http://440hz.ru/trash/download/

    Код (PHP):
    1. <? 
    2.  
    3. // 440hz
    4.  
    5. $string  = "Hello, world!";  
    6. $string .= "\t";  
    7. $string .= "I am a happy worm!" ;
    8. $string .= "\n";  
    9.  
    10. if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) 
    11.    Header('Content-Type: application/force-download'); 
    12. else 
    13.    Header('Content-Type: application/octet-stream'); 
    14.  
    15. Header('Accept-Ranges: bytes'); 
    16. Header('Content-Length: '.strlen($string)); 
    17. Header('Content-disposition: attachment; filename="products.txt"'); 
    18.  
    19. echo $string;  
    20.  
    21. exit(); 
    22.  
    23. ?>
     
  2. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    0
    Адрес:
    леноград
    > Accept-Ranges: bytes

    где поддержка этого в скрипте?
     
  3. 440Hz

    440Hz Активный пользователь
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    это для
    Header('Content-Length: '.strlen($string));

    что б броузер знал что ты длину контента в байтах передаешь
     
  4. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    0
    Адрес:
    леноград
    а Accept-Ranges указывает, что сервер может отдать любую часть файла с точностью до указанной величины.
     
  5. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    0
    Адрес:
    леноград
    > Content-Type: application/force-download

    а октет-стрим он типа не воспринимает или как?
     
  6. 440Hz

    440Hz Активный пользователь
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    это под старые IE заточка.
    куда без напильника-то?
    =)
     
  7. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    0
    Адрес:
    леноград
    и как они себя ведут с октетстримом?
     
  8. 440Hz

    440Hz Активный пользователь
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    попробуй сам...
    =)
     
  9. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    5
    Адрес:
    Рига, Латвия
    440Hz
    Кстати, давно вот пытаюсь понять, как-же сделать скрипт, который умеет отдавать и по частям фаилы - с поддержкой докачки. Не просвятишь на этот счёт? За Header('Accept-Ranges: bytes'); спасибо, давно пытался найти, как браузеру указать размер фаила, что-бы он отображал сколько-же закачалось от общего размера.
     
  10. 440Hz

    440Hz Активный пользователь
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    читаешь $_SERVER. получаешь от туда смещение и отдаешь то, что надо.
     
  11. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    0
    Адрес:
    леноград
    440Hz, у меня нет настолько древних браузеров
     
  12. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    0
    Адрес:
    леноград
  13. vasa_c

    vasa_c Активный пользователь

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    dark-demon, IE6 (отнюдь еще не старый), получив octet-stream пытается показать свою исключительную грамотность и услужливость пользователям, путем самопального определения типа файла.
    То есть, например, картинки выдать на скачку не получится — они будут отрисовываться.
     
  14. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    0
    Адрес:
    леноград
    ну и пусть отрисовываются :) если пользователю не понравится то, что он там увидит - не будет сохранять
     
  15. vasa_c

    vasa_c Активный пользователь

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    Глюпий пользователь даже не поймет как ему сохранить )
     
  16. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    0
    Адрес:
    леноград
    глюпий пользователь не сможет найти скачанный файл.
     
  17. 440Hz

    440Hz Активный пользователь
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    http://440hz.ru/trash/downloadpie/

    Код (PHP):
    1. <? 
    2.  
    3. // 2007 (c) 440hz
    4.  
    5. // отдаваемое файло
    6. $filename = 'queen.mp3';
    7.  
    8. // есл файла нет
    9. if (!file_exists($filename)) { 
    10.     header ("HTTP/1.0 404 Not Found"); 
    11.     exit; 
    12. } 
    13.  
    14. // получим размер файла
    15. $fsize = filesize($filename); 
    16. // дата модификации файла для кеширования
    17. $ftime = date("D, d M Y H:i:s T", filemtime($filename)); 
    18. // смещение от начала файла
    19. $range = 0;
    20.  
    21. // пробуем открыть
    22. $handle = @fopen($filename, "rb"); 
    23.  
    24. // если не удалось
    25. if (!$handle){ 
    26.   header ("HTTP/1.0 403 Forbidden"); 
    27.   exit; 
    28. } 
    29.  
    30. // Если запрашивающий агент поддерживает докачку 
    31. if ($_SERVER["HTTP_RANGE"]) { 
    32.     $range = $_SERVER["HTTP_RANGE"]; 
    33.     $range = str_replace("bytes=", "", $range); 
    34.     $range = str_replace("-", "", $range); 
    35.     // смещаемся по файлу на нужное смещение
    36.     if ($range) {
    37.         fseek($handle, $range);
    38.     } 
    39. } 
    40.  
    41. // если есть смещение
    42. if ($range) { 
    43.   header("HTTP/1.1 206 Partial Content"); 
    44. } else { 
    45.   header("HTTP/1.1 200 OK"); 
    46. } 
    47.  
    48. header("Content-Disposition: attachment; filename="{$filename}""); 
    49. header("Last-Modified: {$ftime}"); 
    50. header("Content-Length: ".($fsize-$range)); 
    51. header("Accept-Ranges: bytes"); 
    52. header("Content-Range: bytes {$range}-".($fsize - 1)."/".$fsize); 
    53.  
    54. // подправляем под IE что б не умничал
    55. if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) 
    56.    Header('Content-Type: application/force-download'); 
    57. else 
    58.    Header('Content-Type: application/octet-stream'); 
    59.  
    60. while(!feof($handle)) {
    61.     $buf = fread($handle,512);
    62.     print($buf);
    63. }
    64.  
    65. fclose($handle);
    66.  
    67. ?>
    Код (Text):
    1.  
    2. www(root):/usr/home/440hz#>wget -v -S -c "http://440hz.ru/trash/downloadpie/index.html"
    3. --17:28:41--  http://440hz.ru/trash/downloadpie/index.html
    4.            => `index.html'
    5. Распознаётся 440hz.ru... 77.234.201.222
    6. Устанавливается соединение с 440hz.ru|77.234.201.222|:80... соединение установлено.
    7. Запрос HTTP послан, ожидается ответ...
    8.   HTTP/1.1 200 OK
    9.   Date: Thu, 13 Dec 2007 14:09:20 GMT
    10.   Server: Apache/2.0.59 (FreeBSD) PHP/5.2.2 with Suhosin-Patch
    11.   X-Powered-By: PHP/5.2.2
    12.   Content-Disposition: attachment; filename="queen.mp3"
    13.   Last-Modified: Thu, 13 Dec 2007 16:45:47 MSK
    14.   Content-Length: 4201788
    15.   Accept-Ranges: bytes
    16.   Content-Range: bytes 0-4201787/4201788
    17.   Keep-Alive: timeout=15, max=100
    18.   Connection: Keep-Alive
    19.   Content-Type: application/octet-stream
    20. Длина: 4 201 788 (4,0M) [application/octet-stream]
    21.  
    22.  8% [=============>                                                                                                                                                      ] 374 604       20,58K/s    ETA 02:18^C
    23. www(root):/usr/home/440hz#>wget -v -S -c "http://440hz.ru/trash/downloadpie/index.html"
    24. --17:29:00--  http://440hz.ru/trash/downloadpie/index.html
    25.            => `index.html'
    26. Распознаётся 440hz.ru... 77.234.201.222
    27. Устанавливается соединение с 440hz.ru|77.234.201.222|:80... соединение установлено.
    28. Запрос HTTP послан, ожидается ответ...
    29.   HTTP/1.1 206 Partial Content
    30.   Date: Thu, 13 Dec 2007 14:09:40 GMT
    31.   Server: Apache/2.0.59 (FreeBSD) PHP/5.2.2 with Suhosin-Patch
    32.   X-Powered-By: PHP/5.2.2
    33.   Content-Disposition: attachment; filename="queen.mp3"
    34.   Last-Modified: Thu, 13 Dec 2007 16:45:47 MSK
    35.   Content-Length: 3822840
    36.   Accept-Ranges: bytes
    37.   Content-Range: bytes 378948-4201787/4201788
    38.   Keep-Alive: timeout=15, max=100
    39.   Connection: Keep-Alive
    40.   Content-Type: application/octet-stream
    41. Длина: 4 201 788 (4,0M), 3 822 840 (3,6M) осталось [application/octet-stream]
    42.  
    43. 14% [++++++++++++++========>                                                                                                                                             ] 597 150       35,92K/s    ETA 01:57^C
    44. www(root):/usr/home/440hz#>wget -v -S -c "http://440hz.ru/trash/downloadpie/index.html"
    45. --17:29:51--  http://440hz.ru/trash/downloadpie/index.html
    46.            => `index.html'
    47. Распознаётся 440hz.ru... 77.234.201.222
    48. Устанавливается соединение с 440hz.ru|77.234.201.222|:80... соединение установлено.
    49. Запрос HTTP послан, ожидается ответ...
    50.   HTTP/1.1 206 Partial Content
    51.   Date: Thu, 13 Dec 2007 14:10:30 GMT
    52.   Server: Apache/2.0.59 (FreeBSD) PHP/5.2.2 with Suhosin-Patch
    53.   X-Powered-By: PHP/5.2.2
    54.   Content-Disposition: attachment; filename="queen.mp3"
    55.   Last-Modified: Thu, 13 Dec 2007 16:45:47 MSK
    56.   Content-Length: 3603190
    57.   Accept-Ranges: bytes
    58.   Content-Range: bytes 598598-4201787/4201788
    59.   Keep-Alive: timeout=15, max=100
    60.   Connection: Keep-Alive
    61.   Content-Type: application/octet-stream
    62. Длина: 4 201 788 (4,0M), 3 603 190 (3,4M) осталось [application/octet-stream]
    63.  
    64. 22% [+++++++++++++++++++++++============>                                                                                                                                ] 944 224       23,31K/s    ETA 01:59^C
    Код (Text):
    1.  
    2. 80.93.56.219 - - [13/Dec/2007:17:09:20 +0300] "GET /trash/downloadpie/index.html HTTP/1.0" 200 417792 "-" "Wget/1.10.2" 124 412680
    3. 80.93.56.219 - - [13/Dec/2007:17:10:30 +0300] "GET /trash/downloadpie/index.html HTTP/1.0" 206 385024 "-" "Wget/1.10.2" 146 379376
    4. 80.93.56.219 - - [13/Dec/2007:17:12:00 +0300] "GET /trash/downloadpie/index.html HTTP/1.0" 206 2629632 "-" "Wget/1.10.2" 146 2625224
     
  18. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    5
    Адрес:
    Рига, Латвия
    Спасибо 440Hz, с меня бочёнок пива когда в Латвию занесёт вас :)
     
  19. maksia

    maksia Активный пользователь

    С нами с:
    8 ноя 2006
    Сообщения:
    45
    Симпатии:
    0
    Адрес:
    Москва
    Сейчас попробовал выполнить скрипт указанный в начале темы на локалхосте и все нормально заработало, а на сервере хостера обрабатывается не правильно. При сохранении вместо имени файла, который указан в скрипте, появляется имя файла скрипта. В чем может быть проблема и как ее устранить?
     
  20. lexa

    lexa Активный пользователь

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
  21. penoplast

    penoplast Активный пользователь

    С нами с:
    23 май 2008
    Сообщения:
    2
    Симпатии:
    0
    Есть сервер на котором расположен сайт mysite.ru и есть другой сервер на котором расположены архивы myarhive.ru. Скрипт расположен на mysite.ru
    Пользователю выдаётся ссылка вида http://mysite.ru/sms/load.php?DDFA6655E6ACE284AC47D1027BB84DE4

    1. При скачивании архива через браузер (скачивание идёт в один поток) по кодированной ссылке всё проходит нормально, архив скачивается полностью распаковывается и всё работает, но не работает докачка, а это важно.
    2. При скачивании с помощью FlashGet (несколько потоков) теряется часть файлов и папок находящихся внутри архива. При этом размер скачанного архива тот же, что и у исходного. Так по крайней мере показывает Тотал Commander.
    3. Пробовал скачивать по прямой ссылке вида http://myarhive.ru/arhive1.rar и сравнивал передаваемые заголовки с заголовками, полученными при скачивании по п. 2. Формируемые заголовки ИДЕНТИЧНЫ.

    Перепробовал разные варианты скриптов, какие нашёл на форумах и мануалах, ничего не помогает.

    Подскажите, что сделано не верно, где кроется ошибка. Буду очень признателен.

    Исходный код (часть его отвечающая за закачку):

    Код (PHP):
    1. <?
    2. // опущена часть кода 
    3.  
    4.         // Подключаем сокет к серверу, т.к. сервер удалённый
    5.         // Берём заголовки и отключаемся
    6.         // $info - ассоциативный массив заголовков
    7.         // $headers - строка заголовков
    8.         // $tab - размер заголовков (в байтах)
    9.         // myarhive.ru - здесь лежат архивы
    10.  
    11.         $fp = fsockopen ("myarhive.ru", 80, $errno, $errstr, 30);
    12.         if(!$fp){
    13.             echo "$errstr ($errno)<br>\n";
    14.         }else{
    15.             fputs ($fp, "GET /$name HTTP/1.0\r\nHost: myarhive.ru\r\n\r\nContent-Type: application/rar\r\nConnection: Close");
    16.             $info = Array();
    17.             $headers = '';
    18.             $tab = 0;
    19.             for($i = 0; $i < 9; $i++){
    20.                 $str = fgets ($fp,1024);
    21.                 $tab += strlen($str);
    22.                 $str = substr($str, 0, strlen($str) - 2);
    23.                 $headers .= $str ."\n";
    24.                 $tmp = explode(": ", $str);
    25.                 $info[$tmp[0]] = $tmp[1];
    26.             }
    27.             fclose ($fp);
    28.         }
    29.  
    30.         // Передаём пользователю заголовки
    31.         // Принимаем файл с сервера и отдаём его юзеру
    32.         $filename = "http://myarhive.ru/".$name; //$name - имя архива
    33.         $fsize = $info['Content-Length'];
    34.         $modified = $info['Last-Modified'];
    35.  
    36.         $fd = @fopen($filename, "rb"); 
    37.         if (!$fd){ 
    38.           header ("HTTP/1.0 403 Forbidden");
    39.           exit; 
    40.         } 
    41.         // Если запрашивающий агент поддерживает докачку 
    42.         if ($_SERVER["HTTP_RANGE"]) { 
    43.           $range = $_SERVER["HTTP_RANGE"]; 
    44.           $range = str_replace("bytes=", "", $range); 
    45.           $range = str_replace("-", "", $range); 
    46.           $range = intval($range);
    47.           fseek($fd, $range);
    48.             
    49.             // передаю заголовки полученные через сокет (часть из них будет ниже изменена)
    50.               foreach($info as $key => $value){
    51.             header($key.": ".$value);
    52.             }
    53.             
    54.             // Формирую заголовки необходимые для докачки
    55.             header("HTTP/1.1 206 Partial Content");                
    56.             header ("Content-Type: application/x-rar-compressed");
    57.             header("Accept-Ranges: bytes");
    58.             header("Content-Length: ".($fsize-$range));
    59.             header("Content-Range: bytes $range-".($fsize -1)."/".$fsize);
    60.             header("Content-Disposition:attachment; filename=".$name);
    61.         } 
    62.  
    63.  
    64.         else{ 
    65.             header("HTTP/1.1 200 OK");             
    66.             header ("Content-Type: application/x-rar-compressed");
    67.             header("Content-Disposition:attachment; filename=".$name);
    68.             header("Content-Length: ".$fsize);
    69.             header("Last-Modified: ".$modified);
    70.             header("Accept-Ranges: bytes");
    71.         }
    72.  
    73.             $buffer = '';
    74.             while (!feof($fd)) {
    75.                 set_time_limit(0);
    76.                 $buffer = fgets($fd, 4096);
    77.                 print $buffer;
    78.                 flush();
    79.             }
    80.         fclose($fd); 
    81.  
    82. // опущена часть кода
    83. ?>
     
  22. penoplast

    penoplast Активный пользователь

    С нами с:
    23 май 2008
    Сообщения:
    2
    Симпатии:
    0
    Для примера полученные заголовки:

    1-й канал
    Скачиваем по ссылке http://myarhive.ru/arhive1.rar
    Код (Text):
    1.  
    2. Fri May 23 11:39:26 2008 HTTP/1.1 200 OK
    3. Fri May 23 11:39:26 2008 Date: Fri, 23 May 2008 07:32:41 GMT
    4. Fri May 23 11:39:26 2008 Server: Apache
    5. Fri May 23 11:39:26 2008 Last-Modified: Thu, 22 May 2008 16:15:17 GMT
    6. Fri May 23 11:39:26 2008 ETag: "4a71d6-23f141-48359c15"
    7. Fri May 23 11:39:26 2008 Accept-Ranges: bytes
    8. Fri May 23 11:39:26 2008 Content-Length: 2355521
    9. Fri May 23 11:39:26 2008 Connection: close
    10. Fri May 23 11:39:26 2008 Content-Type: application/x-rar-compressed
    Скачиваем по ссылке http://mysite.ru/sms/load.php?DDFA6655E6ACE284AC47D1027BB84DE4
    Код (Text):
    1.  
    2. Fri May 23 11:38:16 2008 HTTP/1.1 200 OK
    3. Fri May 23 11:38:16 2008 Server: nginx/0.5.7
    4. Fri May 23 11:38:16 2008 Date: Fri, 23 May 2008 07:38:09 GMT
    5. Fri May 23 11:38:16 2008 Content-Type: application/rar
    6. Fri May 23 11:38:16 2008 Connection: close
    7. Fri May 23 11:38:16 2008 X-Powered-By: PHP/4.4.4
    8. Fri May 23 11:38:16 2008 Last-Modified: Fri, 23 May 2008 07:38:09 GMT
    9. Fri May 23 11:38:16 2008 ETag: "4a71d6-23f141-48359c15"
    10. Fri May 23 11:38:16 2008 Accept-Ranges: bytes
    11. Fri May 23 11:38:16 2008 Content-Length: 2355521
    12. Fri May 23 11:38:16 2008 Content-Disposition: attachment; filename=testarhiv.rar
    13. Fri May 23 11:38:16 2008 Content-transfer-encoding: binary
    2-й канал (возможна докачка):
    Скачиваем по ссылке http://myarhive.ru/arhive1.rar
    Код (Text):
    1. Fri May 23 11:39:27 2008 HTTP/1.1 206 Partial Content
    2. Fri May 23 11:39:27 2008 Date: Fri, 23 May 2008 07:32:43 GMT
    3. Fri May 23 11:39:27 2008 Server: Apache
    4. Fri May 23 11:39:27 2008 Last-Modified: Thu, 22 May 2008 16:15:17 GMT
    5. Fri May 23 11:39:27 2008 ETag: "4a71d6-23f141-48359c15"
    6. Fri May 23 11:39:27 2008 Accept-Ranges: bytes
    7. Fri May 23 11:39:27 2008 Content-Length: 1884417
    8. Fri May 23 11:39:27 2008 Content-Range: bytes 471104-2355520/2355521
    9. Fri May 23 11:39:27 2008 Connection: close
    10. Fri May 23 11:39:27 2008 Content-Type: application/x-rar-compressed
    Скачиваем по ссылке http://mysite.ru/sms/load.php?DDFA6655E6ACE284AC47D1027BB84DE4
    Код (Text):
    1. Fri May 23 11:38:19 2008 HTTP/1.1 206 Partial Content
    2. Fri May 23 11:38:19 2008 Server: nginx/0.5.7
    3. Fri May 23 11:38:19 2008 Date: Fri, 23 May 2008 07:38:12 GMT
    4. Fri May 23 11:38:19 2008 Content-Type: application/rar
    5. Fri May 23 11:38:19 2008 Connection: close
    6. Fri May 23 11:38:19 2008 X-Powered-By: PHP/4.4.4
    7. Fri May 23 11:38:19 2008 Last-Modified: Fri, 23 May 2008 07:38:12 GMT
    8. Fri May 23 11:38:19 2008 ETag: "4a71d6-23f141-48359c15"
    9. Fri May 23 11:38:19 2008 Accept-Ranges: bytes
    10. Fri May 23 11:38:19 2008 Content-Length: 1884417
    11. Fri May 23 11:38:19 2008 Content-Range: bytes 471104-2355520/2355521
    12. Fri May 23 11:38:19 2008 Content-Disposition: attachment; filename=testarhiv.rar
    13. Fri May 23 11:38:19 2008 Content-transfer-encoding: binary
    Как видно из приведённого кода, заголовки отвечающие за докачку идентичны, совпадает до байта.
    По остальным каналам, так же полное совпадение.
     
  23. nAgi

    nAgi Активный пользователь

    С нами с:
    12 сен 2007
    Сообщения:
    43
    Симпатии:
    0
    Можно данный скрипт преписать чтобы скачивать архив

    Есть задача скачивать эксель файл с товарами и архив с фото к товарам.
    Проблему ехселя я решил совместно а вот смачивание недотающих фоток не могу.
    Скрипт сверяет базу свою с базой источника и должен скачать недостающие фотки.
    Есть прямой путь к картинке но не какие манипуляции и попытки получить хотябы вес картинки не дали результата.

    Подскажите есть ли решение чтобы не мучаться?
     
  24. Ururu

    Ururu Активный пользователь

    С нами с:
    21 апр 2009
    Сообщения:
    29
    Симпатии:
    0
    Адрес:
    Москва
    Кстати мысли в слух.
    В опере .rar некоректно пытается скачатся, открывается как .txt :D (по дефолту опера незнает такого расширения).
    А вот с zip и 7z работает на ура.
     
  25. kostyl

    kostyl Guest

    Ururu
    все она знает...