Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Для профи > Скачать файл с сервера


Автор: Serkys 22.11.2006, 12:23
Приветствую.
Есть некоторое количество файлов на сервере. Необходимо дать юзеру скачать любой из них, не показывая при этом реальный урл.
Мой мозг усох, помогите идеями!

Автор: xolod 22.11.2006, 13:48
У меня, например, файл качается примерно таким скриптом. Для упрощения понимания в самом начале я указываю конкретный файл и конкретный путь к нему ($fname, $fpath). В реальности, конечно, отдавать ты будешь то, что хочешь, например с помощью $_GET['id'] и выборки из базы пути-имени.
Код

<?php
$fname = 'somehiddenfile.ext';
$fpath = '/www/data/files/'.$fname;
$fsize = filesize($fpath);
$bufsize = 20000;

if(isset($_SERVER['HTTP_RANGE']))
{
   if(preg_match("/^bytes=(\\d+)-(\\d*)$/", $_SERVER['HTTP_RANGE'], $matches)) {
       $from = $matches[1];
       $to = $matches[2];
       if(empty($to))
       {
           $to = $fsize - 1;
       }
       $content_size = $to - $from + 1;

       header('HTTP/1.1 206 Partial Content');
       header('Content-Range: '.$from.'-'.$to.'/'.$fsize);
       header('Content-Length: '.$content_size);
       header('Content-Type: application/force-download');
       header('Content-Disposition: attachment; filename='.$fname);
       header('Content-Transfer-Encoding: binary');

       if(file_exists($fpath) && $fh = fopen($fpath, 'rb'))
       {
           fseek($fh, $from);
           $cur_pos = ftell($fh);
           while($cur_pos !== FALSE && ftell($fh) + $bufsize < $to+1)
           {
               $buffer = fread($fh, $bufsize);
               print $buffer;
               $cur_pos = ftell($fh);
           }

           $buffer = fread($fh, $to+1 - $cur_pos);
           print $buffer;

           fclose($fh);
       }
       else
       {
           header('HTTP/1.1 404 Not Found');
           exit;
       }
   }
   else
   {
       header('HTTP/1.1 500 Internal Server Error');
       exit;
   }
}
else
{
   header('HTTP/1.1 200 OK');
   header('Content-Length: '.$fsize);
   header('Content-Type: application/force-download');
   header('Content-Disposition: attachment; filename='.$fname);
   header('Content-Transfer-Encoding: binary');

   if(file_exists($fpath) && $fh = fopen($fpath, 'rb')){
       while($buf = fread($fh, $bufsize))
           print $buf;
       fclose($fh);
   }
   else
   {
       header('HTTP/1.1 404 Not Found');
   }
}
?>


Скрипт, разумеется, поддерживает докачку и мультизакачки.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)