Главная
 
Article CMS - лучший катaлог статей!Воскресенье, 19.05.2024, 00:22



Приветствую Вас Гость | RSS
Главная
Меню

Поиск

Новые файлы
[25.08.2009]
ArticleCMS 2.0 (0)
[12.05.2009]
Ротатор опросов (1)
[12.05.2009]
PHP Expert Editor (0)

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Опросы
Что надо добавить/изменить в Article CMS?
Всего ответов: 5

Главная » 2009 » Август » 7 » Скачивание файлов по временным ссылкам
Скачивание файлов по временным ссылкам
19:08
Наверное каждому приходилось сталкиваться с временными ссылками при скачивании фильмов, музыки, программ и т.п. Зачем это делается? Да чтобы другие сайты не размещали ссылки на файлы, которые расположены на нашем сайте. Давайте посмотрим, как написать скрипт, который будет генерить временные ссылки.
В качестве хранения информации о файлах и временных ссылках, будем использовать БД. Таблица files хранит информацию о файлах:

Code

CREATE TABLE `files` (
  `id` INT(10) PRIMARY KEY,
  `title` VARCHAR(255) NOT NULL DEFAULT '',
  `description` TEXT NOT NULL DEFAULT '',
  `filename` VARCHAR(64) NOT NULL DEFAULT '',
  `mimetype` VARCHAR(8) NOT NULL DEFAULT ''
) ENGINE=INNODB DEFAULT CHARSET=cp1251;

Здесь


  • id - уникальный ID файла
  • title - название файла, например, “Текстовой редактор NotePad++“
  • description - описание файла, например, “Бесплатный редактор текстовых файлов (замена стандартного Блокнота) с поддержкой синтаксиса большого количества языков программирования, ориентирован для работы в операционной системе MS Windows“
  • filename - имя файла для скачивания, например, NotePadPP.zip
  • mimetype - MIME-тип файла

Таблица downloads хранит информацию о временных ссылках:

Code

CREATE TABLE `downloads` (
  `file_id` INT(10) NOT NULL DEFAULT 0,
  `uniq_id` VARCHAR(32) NOT NULL DEFAULT '',
  `puttime` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=INNODB DEFAULT CHARSET=cp1251;

Здесь


  • file_id – уникальный ID файла
  • uniq_id – временная ссылка
  • puttime - время создания ссылки

Файлы для скачивания расположены в директории DOCUMENT_ROOT/download/files/. Эта директория должна быть защищена с помощью .htaccess:

Code

Order Allow,Deny
Deny from All

Скрипт, который будет выполнять всю работу - выводить список файлов, генерить временные ссылки, и отдавать файлы на скачивание - DOCUMENT_ROOT/download/index.php

Code

<?php

// Соединяемся с сервером БД
mysql_connect ( 'localhost', 'root', '' );
mysql_query( 'SET NAMES cp1251' );
mysql_select_db ( 'downloads' );

// удаляем устаревшие записи в таблице БД downloads
$query = 'DELETE FROM downloads WHERE puttime < (NOW() - INTERVAL 12 HOUR)';
mysql_query( $query );

$actions = array( 'fileslist', 'getlink', 'download' );

$action = 'fileslist';
if( isset( $_GET['action'] ) and in_array( $_GET['action'], $actions ) ) $action = $_GET['action'];

switch( $action ) {
  case 'fileslist': // список файлов для скачивания
  fileslist(); break;
  case 'getlink': // создаем временную ссылку
  getlink(); break;
  case 'download': // отдаем файл на скачивание
  download(); break;
}

function fileslist() {

  echo '<h3>Файлы для скачивания</h3>'."\n";
  $query = 'SELECT id, title, description, mimetype FROM `files` WHERE 1 ORDER BY title';
  $res = mysql_query( $query );

  echo '<table border="1">'."\n";
  echo '<tr><th>№</th><th>Наименование</th><th>Описание</th><th>Тип</th><th>Скачать</th></tr>'."\n";
  $i = 1;
  while( $file = mysql_fetch_array( $res ) ) {
  echo '<tr>';
  echo '<td>'.$i.'</td>';
  echo '<td>'.$file['title'].'</td>';
  echo '<td>'.$file['description'].'</td>';
  echo '<td>'.$file['mimetype'].'</td>';
  echo '<td><a href="'.$_SERVER['PHP_SELF'].'?action=getlink&id='.$file['id'].'">Скачать</a></td>';
  echo '</tr>'."\n";
  $i++;
  }
  echo '</table>'."\n";
}

function getlink() {

  // если не передан уникальный ID файла - значит пользователь попал сюда по ошибке
  if( !isset( $_GET['id'] ) ) {
  header( 'Location: '.$_SERVER['PHP_SELF'].'?action=fileslist' );
  die();
  }
  $id = (int)$_GET['id'];

  // прежде чем генерить временную ссылку, проверяем, что есть такая запись в таблице БД
  $query = 'SELECT 1 FROM `files` WHERE id='.$id;
  $res = mysql_query( $query );
  if( mysql_num_rows( $res ) == 0 ) {
  header ( 'HTTP/1.1 404 Not Found' );
  die();  
  }
   
  $uniq_id = md5( uniqid(rand(), 1) );
  $query = "INSERT INTO downloads (file_id, uniq_id, puttime)  
  VALUES (".$id.", '".$uniq_id."', NOW())";
  mysql_query( $query );
   
  $link = $_SERVER['PHP_SELF'].'?action=download&id='.$id.'&code='.$uniq_id;
  echo '<p>Для загрузки файла перейдите по <a href="'.$link.'">этой ссылке</a>. ';  
  echo 'Ссылка действительна в течение 12 часов.</p>'."\n";

}

function download() {
   
  // если не передан уникальный ID файла - значит пользователь попал сюда по ошибке
  if( !isset( $_GET['id'] ) ) {
  header( 'Location: '.$_SERVER['PHP_SELF'].'?action=fileslist' );
  die();
  }
  $id = (int)$_GET['id'];
   
  if( !isset( $_GET['code'] ) ) {
  header( 'Location: '.$_SERVER['PHP_SELF'].'?action=fileslist' );
  die();
  }
   
  if( !preg_match( '#[a-f0-9]{32}#', $_GET['code'] ) ) {
  header ( 'HTTP/1.1 404 Not Found' );
  die();
  }
   
  $query = "SELECT 1 FROM downloads WHERE file_id=".$id."  
  AND uniq_id='".$_GET['code']."' AND puttime > (NOW() - INTERVAL 12 HOUR)";
  $res = mysql_query( $query );
  if( mysql_num_rows( $res ) == 0 ) {
  header ( 'HTTP/1.1 404 Not Found' );
  die();  
  }
   
  $query = 'SELECT filename, mimetype FROM `files` WHERE id='.$id;
  $res = mysql_query( $query );
  if( mysql_num_rows( $res ) == 0 ) {
  header ( 'HTTP/1.1 404 Not Found' );
  die();  
  }
  list( $filename, $mimetype ) = mysql_fetch_row( $res );
   
  // если файла нет
  if( !file_exists( './files/'.$filename ) ) {
  header ( 'HTTP/1.1 404 Not Found' );
  die();
  }
   
  // получаем размер файла
  $fsize = filesize( './files/'.$filename );
  // дата модификации файла для кеширования
  $ftime = date( 'D, d M Y H:i:s T', filemtime( './files/'.$filename ) );
  // смещение от начала файла
  $range = 0;
   
  // пробуем открыть
  $handle = @fopen( './files/'.$filename, 'rb' );

  // если не удалось
  if( !$handle ){
  header ( 'HTTP/1.1 404 Not Found' );
  die();
  }
   
  // если запрашивающий агент поддерживает докачку
  if( $_SERVER['HTTP_RANGE'] ) {
  $range = $_SERVER['HTTP_RANGE'];
  $range = str_replace( 'bytes=', '', $range );
  $range = str_replace( '-', '', $range );
  // смещаемся по файлу на нужное смещение
  if ( $range ) fseek( $handle, $range );
  }
   
  // если есть смещение
  if( $range ) {
  header( 'HTTP/1.1 206 Partial Content' );
  } else {
  header( 'HTTP/1.1 200 OK' );
  }
   
  header( 'Content-Disposition: attachment; filename="'.$filename.'"' );
  header( 'Last-Modified: '.$ftime );
  header( 'Content-Length: '.($fsize-$range) );
  header( 'Accept-Ranges: bytes' );
  header( 'Content-Range: bytes '.$range.'-'.($fsize - 1).'/'.$fsize );

  switch( $mimetype ) {
  case 'pdf' : $ctype = 'application/pdf'; break;
  case 'zip' : $ctype = 'application/zip'; break;
  case 'doc' : $ctype = 'application/msword'; break;
  case 'xls' : $ctype = 'application/vnd.ms-excel'; break;
  case 'gif' : $ctype = 'image/gif'; break;
  case 'png' : $ctype = 'image/png'; break;
  case 'jpeg':
  case 'jpg' : $ctype = 'image/jpg'; break;
  case 'mp3' : $ctype = 'audio/mpeg'; break;
  case 'wav' : $ctype = 'audio/x-wav'; break;
  case 'mpeg':
  case 'mpg' :
  case 'mpe' : $ctype = 'video/mpeg'; break;
  case 'mov' : $ctype = 'video/quicktime'; break;
  case 'avi' : $ctype = 'video/x-msvideo'; break;
  default : $ctype = 'application/octet-stream';
  }
   
  header( 'Content-Type: '.$ctype );
   
  readfile( './files/'.$filename );
   
  fclose( $handle );
   
}
   
?>

Обсуждение в одноименной теме на форуме

Просмотров: 1400 | Добавил: respekt | Теги: PHP, MySql, скачать, Файлы | Рейтинг: 0.0/0 |
Всего комментариев: 2
2 respekt  
0
Народ если вдруг появится вопрос по этой теме то пишите на форуме

1 itesiablact  
0
Восхищен

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Архив записей

наши друзья


  • Официальный блог

  • Web-мастер: курс молодого бойца


  • Counter
    Rambler's Top100 ProtoPlex: программы, форум, рейтинг, рефераты, рассылки!

    Реклама





    Copyright MyCorp © 2024