За последние 24 часа нас посетили 6993 программиста и 621 робот. Сейчас ищет 81 программист ...

Временная ссылка для скачивания файла

Тема в разделе "Прочие вопросы по PHP", создана пользователем xeo, 18 июн 2006.

  1. xeo

    xeo Активный пользователь

    С нами с:
    18 июн 2006
    Сообщения:
    4
    Симпатии:
    0
    Добрый день.

    Интересует такой вопрос, нужно сделать скачивание файла для зарегестрированных пользователей на сайте. Чтобы им по запросы выдавалась ссылка на скачивание файла которая будет жить скажем пару часов, сылка в виде www.mysite.com/download.php?23498273
    Чтобы люди не могли догадаться о реальном местоположении файла на сервере.

    Поиск по форуму и в гугле мало к чему привел.
    Может кто подскажет или рабочий такой скрипт, или направленику куда копать дальше ?

    Заранее спасибо.
     
  2. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    вариант 1:
    генерим уникальный ключ, допустим, sha1(время + ип юзера + соль)
    соль - константное значение, хранящееся на сервере.
    ссылку отдаем
    Код (Text):
    1. download.php?k=ключ&t=время
    и в самом скрипте сверяем ключ/время и, соответственно, отдаем/не отдаем файл для скачивания.

    вариант 2:
    опять же генерим уникальный ключ. на этот раз можно совершенно случайное значение. пишем в базу этот ключ и время генерации.
    отдаем ссылку
    Код (Text):
    1. download.php?k=ключ
    в скрипте проверяем, существует ли такая запись в базе, и отдаем/не отдаем на скачивание.
    и еще нужно написать скрипт, который бы удалял устаревшие, т.е. старше 2 часов, записи из базы.

    можно еще варианты реализации придумать. на сколько фантазии хватит. :)
     
  3. vasa_c

    vasa_c Активный пользователь

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    xeo, а что страшного, если они узнают путь?
     
  4. xeo

    xeo Активный пользователь

    С нами с:
    18 июн 2006
    Сообщения:
    4
    Симпатии:
    0
    Большое спасибо за ответ.
    А можно поподробней развернуть ему отдачи файла ?
    просто в пхп совсем новичек так скажем. остальное мне более менее понятно и думаю сделаю. А вот как быть с отдачей файла не до конца понимаю.
     
  5. xeo

    xeo Активный пользователь

    С нами с:
    18 июн 2006
    Сообщения:
    4
    Симпатии:
    0
    так скажем файл, который доступен только узкому кругу лиц.
    например раздача беты программы только бета тестерам, т.е. тем кому разрешено. остальные пусть ждут релиза, и тоже только после регистрации получают файл. :)
     
  6. simpson

    simpson Активный пользователь

    С нами с:
    11 фев 2006
    Сообщения:
    1.650
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    xeo
    в гугле по этой теме много ссылок есть. если лень искать, вот мой класс под пхп4.

    PHP:
    1. <?php
    2.  
    3. define('BUF_SIZE', 8192);
    4. define('CONTENT_TYPE', 'application/octet-stream');
    5. define('CONTENT_DESCRIPTION', 'File Transfer');
    6. define('CON_STATUS_NORMAL', 0);
    7. define('CON_STATUS_ABORTED', 1);
    8. define('CON_STATUS_TIMEOUT', 2);
    9. define('X_POWERED', 'PHP/SIMDownload');
    10.  
    11. class SIMDownload
    12. {
    13.     var $server_vars;
    14.     var $filename;
    15.     var $filesize;
    16.     var $filetime;
    17.     var $filepath;
    18.     var $realpath;
    19.     var $__contentType;
    20.     var $__contentDisposition;
    21.     var $__bufSize;
    22.  
    23.         function SIMDownload($fileName, $filePath='.', $contentDisposition=null, $bufSize=BUF_SIZE, $contentType=CONTENT_TYPE)
    24.         {
    25.             $this->filename = $fileName;
    26.             $this->filepath = preg_replace('~[/]+$~', '', $filePath);
    27.             $this->realpath = $this->filepath . '/' . $this->filename;
    28.             if (!file_exists($this->realpath))
    29.             {
    30.                 $this->__404();
    31.                 exit;
    32.             }
    33.             $this->filesize = filesize($this->realpath);
    34.             $this->filetime = filemtime($this->realpath);
    35.             $this->__bufSize = $bufSize;
    36.             $this->__contentType = $contentType;
    37.             $this->__contentDisposition = (!empty($contentDisposition)) ? $contentDisposition : $fileName;
    38.             $this->server_vars = &$_SERVER;
    39.         }
    40.         function download()
    41.         {
    42.             $realpath = $this->realpath;
    43.             if (!file_exists($realpath))
    44.             {
    45.                 $this->__404();
    46.                 exit;
    47.             }
    48.             $fp = fopen($realpath, 'rb');
    49.             if (!is_resource($fp))
    50.             {
    51.                 $this->__403();
    52.                 exit;
    53.             }
    54.             if (isset($this->server_vars['HTTP_RANGE']))
    55.             {
    56.                 preg_match('~bytes=(\d+)-~', $this->server_vars['HTTP_RANGE'], $out);
    57.                 $range = intval($out[1]);
    58.                 fseek($fp, $range);
    59.                 $this->__206($range);
    60.             }
    61.             else
    62.             {
    63.                 $this->__200();
    64.             }
    65.             while (!feof($fp) and connection_status() == CON_STATUS_NORMAL)
    66.             {
    67.                 $content = fread($fp, $this->__bufSize);
    68.                 print $content;
    69.             }
    70.             fclose($fp);
    71.             exit;
    72.         }
    73.         function __getGMT($time=null)
    74.         {
    75.             $offset = date('O');
    76.             if ($offset{0} == '+') $roffset = '-';
    77.             else $roffset = '+';
    78.             $roffset .= $offset{1} . $offset{2};
    79.             if (empty($time))
    80.             {
    81.                         $time = time();
    82.                 }
    83.                 return (date('D, d M Y H:i:s', $time+$roffset*3600) . ' GMT');
    84.         }
    85.         function __200()
    86.         {
    87.             header('HTTP/1.1 200 OK');
    88.             header('Date: ' . $this->__getGMT());
    89.             header('X-Powered-By: ' . X_POWERED);
    90.             header('Expires: Mon, 27 Jan 1986 14:40:00 GMT');
    91.             header('Last-Modified: ' . $this->__getGMT($this->filetime));
    92.             header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    93.             header('Pragma: Public');
    94.             header('Accept-Ranges: bytes');
    95.             header('Content-Disposition: attachment; filename="' . $this->__contentDisposition . '"');
    96.             header('Content-Type: ' . $this->__contentType);
    97.             header('Content-Description: ' . CONTENT_DESCRIPTION);
    98.             header('Content-Transfer-Encoding: binary');
    99.             header('Content-Length: ' . $this->filesize);
    100.             header('Proxy-Connection: close');
    101.         }
    102.         function __206($range=0)
    103.         {
    104.             $length = $this->filesize-$range;
    105.             $offset = $this->filesize-1;
    106.             header('HTTP/1.1 206 Partial Content');
    107.             header('Date: ' . $this->__getGMT());
    108.             header('X-Powered-By: ' . X_POWERED);
    109.             header('Expires: Mon, 27 Jan 1986 14:40:00 GMT');
    110.             header('Last-Modified: ' . $this->__getGMT($this->filetime));
    111.             header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    112.             header('Pragma: Public');
    113.             header('Accept-Ranges: bytes');
    114.             header('Content-Disposition: attachment; filename="' . $this->__contentDisposition . '"');
    115.             header('Content-Type: ' . $this->__contentType);
    116.             header('Content-Description: ' . CONTENT_DESCRIPTION);
    117.             header('Content-Transfer-Encoding: binary');
    118.             header("Content-Range: bytes $range-$offset/" . $this->filesize);
    119.             header('Content-Length: ' . $length);
    120.             header('Proxy-Connection: close');
    121.         }
    122.         function __403()
    123.         {
    124.             header('HTTP/1.0 403 Forbidden', true, 403);
    125.             header('X-Powered-By: ' . X_POWERED);
    126.             header('Proxy-Connection: close');
    127.         }
    128.         function __404()
    129.         {
    130.             header('HTTP/1.0 404 Not Found', true, 404);
    131.             header('X-Powered-By: ' . X_POWERED);
    132.             header('Proxy-Connection: close');
    133.         }
    134. }
    135.  
    136. ?>
    использовать довольно просто.

    PHP:
    1. <?php
    2. include 'download.class.php'; // подключаем класс выше
    3. $filename = 'somefile.txt'; // имя скачиваемого файла
    4. $path = '/path/to/filedir'; // путь до директории с файлом
    5.  
    6. $D = new SIMDownload($filename, $path);
    7. $D->download();
    8. ?>
     
  7. xeo

    xeo Активный пользователь

    С нами с:
    18 июн 2006
    Сообщения:
    4
    Симпатии:
    0
    Большое спасибо!!!!
     
  8. a-p-ermakov

    a-p-ermakov Активный пользователь

    С нами с:
    20 май 2012
    Сообщения:
    1
    Симпатии:
    0
    Раскажите пожалуйста куда этот код засунуть. Большой код в один файл, а маленький код который в конце в другой?
    И надо ли что то в классе менять?
     
  9. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.419
    Симпатии:
    1.743
    теме 6 лет
     
  10. Yankovitz

    Yankovitz Активный пользователь

    С нами с:
    21 ноя 2014
    Сообщения:
    193
    Симпатии:
    6
    Все равно интересно. Хоть и ещё 5 лет прошло :))
     
  11. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.501
    Симпатии:
    599