Вы не зашли.
Главная » PHP » Отдаем файл через скрипт, с возможностью докачки.
#1. Admin Off (-1)
Administrator
2008.03.05 09:09
Данная задача оказалась не такой простой как думалось мне сначала, 1 что я сделал - это стал ковырять PEAR класс HTTP_Download, вроде бы все бы ничего, но... то ли я торможу, то ли этот класс... Проблемы с заголовкам были у меня с ним. Не отдавался иногда Content-Length. Ну и еще всякие непонятные проблемы с гзипом. Сутки с ним ипался, ладно, решил забить. Полез искать инфу по заголовкам и возможно готовые решения не на основе этого PEAR класса. Решения собсна нашел... НО, во всех этих решениях отдавался именно файл, а мне нужно отдать переменную, да и функционал этих решений не ахти.
А так же не учитывается случай если браузер или через что там качают, не поддерживает докачку. Такое тоже бывает, WAP все-таки smile
Кароче на основе одной функции сделал свою, потестил с телефонов, все Ок smile
Йузаем wink
Код:
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;}?>
ну и работает соответственно примерно так
Код:
span style="color: #0000BB"><?php$file = file_get_contents('file.zip');// Файл, имя, аттач, MIME, кодировкаgetf($file,'name.zip',false,false,false);?>
Отредактировано Gemorroj (2008.04.19 22:10)
сердце пронзенное ветром
#2. Helqg Off (2)
Участник
2008.03.09 18:06
Эээ... А по русски? Я качаю файл. Затем перестаю. Через час прихожу и докачиваю. / т.Е. Скрипт знает сколько я скачал?
Стране нужны автобусы!
#3. Gemorroj Off (107)
Administrator
2008.03.10 16:04
нет) при докачке отправляется качалкой твоей заголовок Accept-Range - откуда начать закачивать файл, а не с первого байта.
#4. Helqg Off (2)
Участник
2008.03.10 20:08
Т.Е. Моя качалка знает откуда докачивать и передает это на сервер? Фигасе О_о. Ты на каких телефонах тестил? Мой такое точно не умеет.

Добавлено спустя   6 минут  3 секунды:
Всмысле, браузер родной. FGet конечно докачает. // хотя стоп. Я что то не пойму. Что я должен передать скрипту? Только адрес файла?
Стране нужны автобусы!
#5. Gemorroj Off (107)
Administrator
2008.03.11 10:10
Да, твоя качалка знает откуда качать) Ты должен передать только адрес, а качалка сделает остальное, кучу заголовков еще примет и отдаст на сервер. Тестил на разных телефонах, есть правда кое-какие проблемы, многие скачивают файл и не сохраняют его =/
#6. Gemorroj Off (107)
Administrator
2008.04.19 22:10
нашел ошибку... вобщем с кодировками траблы. кирилица в UTF-8 занимает 2 байта на символ, что несовместимо с бинарными файлами. добавил mb_detect_encoding - детектирование кодировки, проблема пропала.
Страниц: 1
Главная
WEB
PunBB Mod v0.6.2
0.014 s