• Главная
  • » PHP
  • » Отдаем файл через скрипт, с возможностью докачки.

#1 2008.03.05 09:52

Admin
Administrator
Зарегистрирован: 2007.11.03
Сообщений: 95
Карма: -1
Профиль

Отдаем файл через скрипт, с возможностью докачки.

Данная задача оказалась не такой простой как думалось мне сначала, 1 что я сделал - это стал ковырять PEAR класс HTTP_Download, вроде бы все бы ничего, но... то ли я торможу, то ли этот класс... Проблемы с заголовкам были у меня с ним. Не отдавался иногда Content-Length. Ну и еще всякие непонятные проблемы с гзипом. Сутки с ним ипался, ладно, решил забить. Полез искать инфу по заголовкам и возможно готовые решения не на основе этого PEAR класса. Решения собсна нашел... НО, во всех этих решениях отдавался именно файл, а мне нужно отдать переменную, да и функционал этих решений не ахти.
А так же не учитывается случай если браузер или через что там качают, не поддерживает докачку. Такое тоже бывает, WAP все-таки smile
Кароче на основе одной функции сделал свою, потестил с телефонов, все Ок smile
Йузаем wink

Код:

1
span style="color: #0000BB"><?php// Содержимое файла, имя файла, аттач (опционально), MIME (опционально), кодировка (опционально)function getf($f, $name, $attach, $mime, $charset){global $_SERVER;// кодировкаif(!$charset){$charset = mb_detect_encoding($f,'UTF-8,Windows-1251,KOI8-R,ASCII,ISO-8859-1,JIS,EUC-JP,SJIS');}mb_internal_encoding($charset);// Длина файла$len = mb_strlen($f);$out = $f;// "От" и "До" по умолчанию$file_range = array('from' => 0, 'to' => $len);// Если докачкаif($_SERVER['HTTP_RANGE']){if(preg_match('/bytes=(\d+)-(\d*)/i', $_SERVER['HTTP_RANGE'], $matches)){// "От", "До" если "До" нету, "До" равняется размеру файла$file_range = array('from' => $matches[1], 'to' => ($matches[2] == '') ? $len : $matches[2]);// Режем переменную в соответствии с даннымиif($file_range){$out = mb_substr($out, $file_range['from'], $file_range['to']+1);}}}// Заголовки...if($file_range['from']){header('HTTP/1.0 206 Partial Content');}else{header('HTTP/1.0 200 OK');}// Ставим MIME в зависимости от расширенияif(!$mime){$info = pathinfo($name);switch(strtolower($info['extension'])){default:$mime = 'application/octet-stream';break;case 'jar':$mime = 'application/java-archive';break;case 'jad':$mime = 'text/vnd.sun.j2me.app-descriptor';break;case 'cab':$mime = 'application/vnd.ms-cab-compressed';break;case 'sis':$mime = 'application/vnd.symbian.install';break;case 'zip':$mime = 'application/x-zip';break;case 'rar':$mime = 'application/x-rar-compressed';break;case '7z':$mime = 'application/x-7z-compressed';break;case 'gz':case 'tgz':$mime = 'application/x-gzip';break;case 'bz':case 'bz2':$mime = 'application/x-bzip';break;case 'jpg':case 'jpe':case 'jpeg':$mime = 'image/jpeg';break;case 'gif':$mime = 'image/gif';break;case 'png':$mime = 'image/png';break;case 'txt':case 'dat':case 'php':case 'php5':case 'htm':case 'html':case 'wml':case 'css':$mime = 'text/plain';break;case 'mmf':$mime = 'application/x-smaf';break;case 'mid':$mime = 'audio/mid';break;case 'mp3':$mime = 'audio/mpeg';break;case 'amr':$mime = 'audio/amr';break;case 'wav':$mime = 'audio/x-wav';break;case 'mp4':$mime = 'video/mp4';break;case 'wmv':$mime = 'video/x-ms-wmv';break;case '3gp':$mime = 'video/3gpp';break;case 'avi':$mime = 'video/x-msvideo';break;case 'mpg':case 'mpe':case 'mpeg':$mime = 'video/mpeg';break;case 'pdf':$mime = 'application/pdf';break;}}header('Content-Type: '.$mime);header('Content-Transfer-Encoding: binary');//header('Last-Modified: '.gmdate('r', time()));// Кэшheader('Cache-Control: public, must-revalidate, max-age=0');header('Pragma: cache');header('Accept-Ranges: bytes');header('Content-Length: '.mb_strlen($out));// Если докачкаif($_SERVER['HTTP_RANGE']){header('Content-Range: bytes '.$file_range['from'].'-'.$file_range['to'].'/'.$len);}// Хэш$etag = md5($f);$etag = substr($etag, 0, 4).'-'.substr($etag, 5, 5).'-'.substr($etag, 10, 8);header('ETag: "'.$etag.'"');//header('Connection: close');header('Connection: Keep-Alive');header('Keep-Alive: timeout=15, max=50');// Если отдаем как аттачif($attach){header('Content-Disposition: attachment; filename="'.$name.'"');}print $out;return;}?>

ну и работает соответственно примерно так

Код:

1
span style="color: #0000BB"><?php$file = file_get_contents('file.zip');// Файл, имя, аттач, MIME, кодировкаgetf($file,'name.zip',false,false,false);?>

Отредактировано Gemorroj (2008.04.19 22:05)


сердце пронзенное ветром

Неактивен

#2 2008.03.09 18:22

Helqg
Участник
Откуда: 52 регион
Зарегистрирован: 2008.01.23
Сообщений: 306
Карма: 2
Профиль

Re: Отдаем файл через скрипт, с возможностью докачки.

Эээ... А по русски? Я качаю файл. Затем перестаю. Через час прихожу и докачиваю. / т.Е. Скрипт знает сколько я скачал?


Стране нужны автобусы!

Неактивен

#3 2008.03.10 16:21

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Отдаем файл через скрипт, с возможностью докачки.

нет) при докачке отправляется качалкой твоей заголовок Accept-Range - откуда начать закачивать файл, а не с первого байта.

Неактивен

#4 2008.03.10 20:04

Helqg
Участник
Откуда: 52 регион
Зарегистрирован: 2008.01.23
Сообщений: 306
Карма: 2
Профиль

Re: Отдаем файл через скрипт, с возможностью докачки.

Т.Е. Моя качалка знает откуда докачивать и передает это на сервер? Фигасе О_о. Ты на каких телефонах тестил? Мой такое точно не умеет.

Добавлено спустя   6 минут  3 секунды:
Всмысле, браузер родной. FGet конечно докачает. // хотя стоп. Я что то не пойму. Что я должен передать скрипту? Только адрес файла?


Стране нужны автобусы!

Неактивен

#5 2008.03.11 10:09

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Отдаем файл через скрипт, с возможностью докачки.

Да, твоя качалка знает откуда качать) Ты должен передать только адрес, а качалка сделает остальное, кучу заголовков еще примет и отдаст на сервер. Тестил на разных телефонах, есть правда кое-какие проблемы, многие скачивают файл и не сохраняют его =/

Неактивен

#6 2008.04.19 22:09

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Отдаем файл через скрипт, с возможностью докачки.

нашел ошибку... вобщем с кодировками траблы. кирилица в UTF-8 занимает 2 байта на символ, что несовместимо с бинарными файлами. добавил mb_detect_encoding - детектирование кодировки, проблема пропала.

Неактивен

  • Главная
  • » PHP
  • » Отдаем файл через скрипт, с возможностью докачки.

Дополнительно

forum.wapinet.ru

PunBB Mod v0.6.2
0.010 s