Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: скачивание файлов заголовками
 
 автор: elenaki   (09.08.2010 в 10:24)   письмо автору
 
 

ох уж мне эти заголовки! никак мне их не осилить... уже 10 функций по скачиванию перепробовала, ни одна не работает.

надо организовать скачивание больших файлов с сервера. пока не нужно никаких докачек и счетчиков. просто по ссылке не открывать файл, а предлагать его сохранить. тип файла может быть любой: doc, jpg, png, pdf, txt.

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

это последняя:

function downloadFile10 ($filename, $path,  $mimetype='application/octet-stream') {    
    if (!file_exists($_SERVER["DOCUMENT_ROOT"].$path."/".$filename)) 
        die('Файл не найден');    
    
    $from=$to=0; 
    $cr=NULL;
        
        if (isset($_SERVER['HTTP_RANGE'])) {        
            $range=substr($_SERVER['HTTP_RANGE'], strpos($_SERVER['HTTP_RANGE'], '=')+1);        
            $from=strtok($range, '-');        
            $to=strtok('/'); 
        
        if ($to>0) $to++;        
        if ($to) $to-=$from;        
        
        header('HTTP/1.1 206 Partial Content');        
        $cr='Content-Range: bytes ' . $from . '-' . (($to)?($to . '/' . $to+1):filesize($_SERVER["DOCUMENT_ROOT"].$path."/".$filename));    
        } 
        else    
        header('HTTP/1.1 200 Ok');    
        
        $etag=md5($_SERVER["DOCUMENT_ROOT"].$path."/".$filename);    
        $etag=substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);    
        
        header('ETag: "' . $etag . '"');    
        header('Accept-Ranges: bytes');    
        header('Content-Length: ' . (filesize($_SERVER["DOCUMENT_ROOT"].$path."/".$filename)-$to+$from));    
            if ($cr) header($cr);    
        header('Connection: close');    
        header('Content-Type: ' . $mimetype);    
        header('Last-Modified: ' . gmdate('r', filemtime($_SERVER["DOCUMENT_ROOT"].$path."/".$filename)));    
        
        $f=fopen($_SERVER["DOCUMENT_ROOT"].$path."/".$filename, 'rb');    
        header('Content-Disposition: attachment; filename="' . $filename . '";');    
        
            if ($from) fseek($f, $from, SEEK_SET);    
            if (!isset($to) or empty($to)) {        
                $size=filesize($_SERVER["DOCUMENT_ROOT"].$path."/".$filename)-$from;    
            }
            else {        
                $size=$to;    
            }    
            $downloaded=0;    
            
            while(!feof($f) and !connection_status() and ($downloaded<$size)) {        
                echo fread($f, 512000);        
                $downloaded+=512000;        
                flush();    
                echo "downloaded: ".$downloaded."<br>";
            }    
            fclose($f);
}

  Ответить  
 
 автор: neadekvat   (09.08.2010 в 10:38)   письмо автору
 
   для: elenaki   (09.08.2010 в 10:24)
 

У какой-то функции (возможно, header) в документации указан пример, рабочий:

<?php
    
if (file_exists($tmp_name)) {
            
header('Content-Description: File Transfer');
            
header('Content-Type: application/x-zip-compressed');
            
header('Content-Disposition: attachment; filename='.basename($tmp_name));
            
header('Content-Transfer-Encoding: binary');
            
header('Expires: 0');
            
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            
header('Pragma: public');
            
header('Content-Length: ' filesize($tmp_name));
            
ob_clean();
            
flush();
            
readfile($tmp_name);
            die;
        }


Забыл сказать, что это для архивов (Content-Type: application/x-zip-compressed), для разных файлов необходимо указать Content-Type: application/octet-stream

  Ответить  
 
 автор: elenaki   (09.08.2010 в 10:47)   письмо автору
 
   для: neadekvat   (09.08.2010 в 10:38)
 

у меня нет tmp_name, у меня есть имя файла и путь к нему. и это не всегда будет zip.

ОК. поменяла пути к файлу, вроде, работает. пока не очень большие закачиваю, 4Мб. дальше видно будет.

спасибо

  Ответить  
 
 автор: Trianon   (09.08.2010 в 11:06)   письмо автору
 
   для: elenaki   (09.08.2010 в 10:47)
 

Фактически полей заголовка нужно отправить три.
Content-Type: application/octet-stream; name="file.ext"
Content-Disposition: attachment/octet-stream; name="file.ext"
Content-Length: размер_в_байтах

остальное - частичная закачка, управление кешированием - по желанию.
собственно, можно и размер не отправлять. Но он если известен, почто не выслать...

  Ответить  
 
 автор: .....   (09.08.2010 в 11:44)
 
   для: neadekvat   (09.08.2010 в 10:38)
 

>header('Content-Transfer-Encoding: binary');
Content-Transfer-Encoding в http вроде не применяется.
есть Transfer-Encoding,: Content-Encoding

в функции что-то похожее на Transfer-Encoding: chunked
при этом как-бы с поддержкой докачки (нет возможности проверить как работает,)


Examples of byte-content-range-spec values, assuming that the entity
   contains a total of 1234 bytes:


      . The first 500 bytes:
       bytes 0-499/1234

      . The second 500 bytes:
       bytes 500-999/1234

      . All except for the first 500 bytes:
       bytes 500-1233/1234

      . The last 500 bytes:
       bytes 734-1233/1234


 When an HTTP message includes the content of a single range (for
   example, a response to a request for a single range, or to a request
   for a set of ranges that overlap without any holes), this content is
   transmitted with a Content-Range header, and a Content-Length header
   showing the number of bytes actually transferred. For example,


       HTTP/1.1 206 Partial content
       Date: Wed, 15 Nov 1995 06:25:24 GMT
       Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
       Content-Range: bytes 21010-47021/47022
       Content-Length: 26012
       Content-Type: image/gif
[/i]



Content-Type здесь изменяется в зависимости от того с какими параметрами вызывается функция
>>downloadFile10 ($filename, $path, $mimetype='application/octet-stream')
чтобы скачивалось всё нужно не передавать последний параметр при вызове

  Ответить  
 
 автор: .....   (09.08.2010 в 11:48)
 
   для: .....   (09.08.2010 в 11:44)
 

ups// chunked не реализрвывалось кажеться :)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования