Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Скачивание файла
Форумы портала PHP.SU » PHP » Программирование на PHP » Скачивание файла

Страниц (1): [1]
 

1. Viper - 02 Февраля, 2010 - 09:25:09 - перейти к сообщению
Я понимаю что тема изъедена аки старые носки, но все же...

Есть проблема. Мурзила неверно скачивает файл. т.е. к примеру файл весит 10кб, а скачивается 0
Сначала думал проблема в пути к файлу, но нет все нормально. На мурзиле плагин DownThemAll скачал этот же файл без проблем.

код отдачи такой
PHP:
скопировать код в буфер обмена
  1. @ini_set('zlib.output_compression', 'Off');
  2. header("Expires: Tue, 1 Jan 1980 00:00:00 GMT");
  3. header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
  4. header("Cache-Control: no-store, no-cache, must-revalidate");
  5. header("Cache-Control: post-check=0, pre-check=0", false);
  6. header("Pragma: no-cache");
  7. header("X-Powered-By: KA");
  8. header("Accept-Ranges: bytes");
  9. header("Content-Type: application/force-download");
  10. header("Connection: close");
  11. header("Content-disposition: attachment; filename=".basename(str_replace($mosConfig_absolute_path, $mosConfig_live_site, $ka_path_torrent_movie).$filepath));
  12. header("Content-Transfer-Encoding: binary");
  13. @readfile($filepath);


К тому же есть такой момент... Хочу переделать чтобы отдавалось кусками, сейчас же php гребет все в буфер, а потом только отдает.

PS! Не пинайте сильно, эт мой первый печальный опыт антиличивания...
PS1! На php.net в комментах есть простенькая функция http://ua2.php.net/manual/en/fun...adfile.php#88549 может её использовать? Или как быть если файл к примеру 4 гига будет?!
2. Мелкий - 02 Февраля, 2010 - 09:37:22 - перейти к сообщению
Viper пишет:
Мурзила неверно скачивает файл. т.е. к примеру файл весит 10кб, а скачивается 0

т.е. неверно определяет размер или не скачивает?
Для размера, вы пропустили header('Content-Length: ' . filesize($file));

Там в комментах есть smartReadFile - вроде то, что нужно.
3. Viper - 02 Февраля, 2010 - 10:21:50 - перейти к сообщению
Мелкий воспользовался той функцией. пока что работает. дома проверю на больших файлах...
(Добавление)
хех... вот и баг... опять гребет в буфер(какого ...я), а потом отдает. да ещё не полностью... из файла размером 77 мб, отдало 28 мб...

что-то не совсем понял что произошло...

PS! Опять же плагином скачалось полностью, но нагрузив процесс апача до 100% проца...
Та же ситуация и с IE. Скачивает через раз "сожрав" весь проц...
4. valenok - 03 Февраля, 2010 - 08:46:31 - перейти к сообщению
А если отдавать поток по чуть-чуть, потом ставить usleep
5. Viper - 03 Февраля, 2010 - 15:06:28 - перейти к сообщению
valenok пишет:
А если отдавать поток по чуть-чуть, потом ставить usleep

в смысле поток? поподробнее пожалуйста.
сейчас функция выглядит как

PHP:
скопировать код в буфер обмена
  1. function downloadFile($filepath) {
  2.         if (!file_exists($filepath)) {
  3.                 header('HTTP/1.0 404 Not Found');
  4.                 return;
  5.         }
  6.         $size = filesize($filepath);
  7.         $time = date('r', filemtime($filepath));
  8.         $fm = @fopen($filepath, 'rb');
  9.         if (!$fm) {
  10.                 header('HTTP/1.0 505 Internal server error');
  11.                 return;
  12.         }
  13.         $begin = 0;
  14.         $end = $size;
  15.         if (isset($_SERVER['HTTP_RANGE'])) {
  16.                 if (preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) {
  17.                         $begin = intval($matches[1]);
  18.                         if (!empty($matches[2])) $end = intval($matches[2]);
  19.                 }
  20.         }
  21.         ignore_user_abort(true);
  22.         @ini_set('zlib.output_compression', 'Off');
  23.         if ($begin > 0 || $end < $size) {
  24.                 header('HTTP/1.0 206 Partial Content');
  25.         } else {
  26.                 header('HTTP/1.0 200 OK');
  27.         }
  28.         header('Content-Type: application/octet-stream');
  29.         header('Cache-Control: public, must-revalidate, max-age=0');
  30.         header('Pragma: no-cache');
  31.         header('X-Powered-By: Kinoarhiv');
  32.         header('Accept-Ranges: bytes');
  33.         header('Content-Length:'.($end - $begin));
  34.         header('Content-Range: bytes '.$begin - $end / $size);
  35.         header('Content-Disposition: inline; filename='.basename($filepath));
  36.         header('Content-Transfer-Encoding: binary\n');
  37.         header('Last-Modified: '.$time);
  38.         header('Connection: close');
  39.         $cur = $begin;
  40.         fseek($fm, $begin, 0);
  41.         while(!feof($fm) && $cur < $end && (connection_status() == 0)) {
  42.                 echo fread($fm, min(1024*16, $end-$cur));
  43.                 $cur+=1024*16;
  44.                 usleep(1);
  45.         }
  46. }


usleep помог только в том плане что теперь мозилла хватает скачивание файла с первого раза и IE тоже, но загрузка сервера по прежнему 80-90% при скачивании и файл скачивается ровно на 28 819 678 байт хотя исходный размер намного больше.
6. JustUserR - 03 Февраля, 2010 - 16:28:41 - перейти к сообщению
Viper Вообще usleep на одну миллесекунду не даст нормальной задержки конечно - я воообще сомневаюсь что в многопоточных системах можно сделать такою паузу - по моим наблюдениям ниже 15 мск это бесполезно - так что поставьте значеия побольше и порции отдачи данных тоже сделайте побольше

 

Powered by ExBB FM 1.0 RC1