В последнее время всё чаще при скачивании фильмов, или файлов сталкиваюсь с временными ссылками. Зачем это делается? Во первых что бы другие сайты не размещали ссылки на файлы, которые распространяются на вашем сайте. Во вторых, таким образом, файлы можно защитить от массового скачивания, с одного IP. Или из подсети.
Возможно вы давно задумались о создании такого скрипта, либо о его покупке. Но толи цена кусается, то ли вам некогда придумывать свой скрипт. По этому, в этой статье я решил написать, о том как в течении 5-10 минут можно написать скрипт, для генерации временных ссылок.
В качестве хранения файлов и временных ссылок, будем использовать БД MySQL. Я не буду вводить вас в основы работы с БД MySQL. Не буду говорить о том, что это такое. Об этом написано не мало статей, предполагается что вы и так знаете, что это, и как с ним работать.
Начинаем разрабатывать БД. Я предлагаю самую простую структуру БД, я не создаю полноценный скрипт, а просто объясняю вам как это сделать.
Давайте представим, что у вас есть сайт на котором вы выкладываете ссылки на фильмы. У вас есть таблица по хранению данных о фильмах, допустим структура будет такой:
CREATE TABLE film (id int(30) auto_increment, name text(255) NOT NULL, date datetime DEFAULT '0000-00-00 00:00:00', genre text(100) NOT NULL, description text NOT NULL, author text(20) NOT NULL, file_name text(255), size int(30) NOT NULL, mime_tip text(80) NOT NULL, PRIMARY KEY (id));
id – это порядковый номер записи.
name – Название фильма
date - Дата добавления
genre - Жанр
description - Описание
author – Кто добавил
file_name – Оригинальное имя файла
size – Размер файла(храним в Битах).
mime_tip - тип загружаемого файла
Это наша первая таблица, ниже представлена структура второй таблицы, где мы будем хранить временные ссылки.
CREATE TABLE download (id int(255) auto_increment, f_id int(30) NOT NULL, links text(100) NOT NULL, data_start text NOT NULL, PRIMARY KEY (id));
id - Порядковый номер записи.
f_id – Это порядковый номер файла(получаем из таблицы film, по этому полю будем устанавливать связь)
links – Тут мы храним нашу временную ссылку.
data_start – Дата создания ссылки.
Так, с БД определились.
Теперь создаём новую БД, заносим туда наши таблицы, и делаем 3 записи в первую таблицу, предпологается что у вас уже есть скрипт по загрузке файлов на сервер, или что то в этом роде. По этому этот этап мы пропускаем.
Запросы для таблицы film:
INSERT INTO film (name,date,genre,description,author,file_name,size) VALUES ('Фильм №1',NOW(),'Аниме','Описание первого фильма','Админ','anime.avi','776609408'); INSERT INTO film (name,date,genre,description,author,file_name,size) VALUES ('Фильм №2',NOW(),'Комедия','Описание второго фильма','Админ','kom.vob','1008192384'); INSERT INTO film (name,date,genre,description,author,file_name,size) VALUES ('Фильм №3',NOW(),'Ужасы','Описание третьего фильма','Админ','strax.avi','87809408');
Приступаем к созданию файла конфигурации. Создаём файл и называем его config.php
< ?php $host="localhost"; //Путь к MySQL $user="root"; // логин пользователя $password="password"; // пароль $db_name="db_102"; // Имя БД $url = "http://localhost/test/link"; //Путь к скрипту $time_end = "259200"; // Время жизни ссылки, указываем в секундах. Сейчас 3 суток. $downloads = "films/catalog/downloads"; //Путь где у нас хранятся файлы. (можно указать больше) mysql_connect($host,$user,$password) or die (mysql_error()); //Конектимся с БД mysql_select_db($db_name) or die (mysql_error()); mysql_query('SET NAMES cp1251;'); // Если траблы при выборке, явно задаём кодировку. ?>
Теперь создаём файл index.php. Его код буду давать по частям с описанием. Первой строкой подключаем наш файл config.php
include("config.php");
Делаем полную выборку из БД.
$query=mysql_query("SELECT * FROM film ORDER BY date DESC") or die (mysql_error()); while($rows=mysql_fetch_array($query)) { $date = date("d-m-Y h:i:s", strtotime($rows['date'])); echo"< table width="80%" align="center" cellpadding="0" cellspasing="0" class="table"> < tr>< td wid>Название : < b>{$rows['name']}< /b>< br> Дата добавления : < b>{$date}< /b> < /td>< td align="right">< a href="index.php?download={$rows['id']}&film={$rows['file_name']}"> Скачать < /a> Размер файла : < b>{$rows['size']}< /b>< /td>< /tr> < tr>< td colspan="2" class="content">Жанр : < b>{$rows['genre']}< /b>< BR>< BR>{$rows['description']}< BR>< BR>< p align="right">Добавил : < b>{$rows['author']}< /b>< /p>< /td>< /tr> < /table>< BR>"; }
Запрос очень простой, по этому считаю, что комментарии излишни. Закрываем коннект с БД:
mysql_close();
Теперь приступаем к генерации временных ссылок.
И так пользователь прочитав о фильме, жмёт на лику «Скачать». Передаётся соответствующий запрос, и вот с этого места начнём, поподробней. Пользователь нажал, выполняется условие,
if (isset($_GET['download']))
Первым делом проверяем что бы переменная $_GET['download'], была числом, это не критично но всё же.
В этом нам поможет функция is_numeric.
if (!is_numeric($_GET['download'])) { echo"< span class="er">Хакер?? Хе-хе!!!< /span>";exit();}
В echo можем поиздеваться! )
После, с помощью функции exit(); - прекращаем работу скрипта.
Если всё ок, т.е. переменная $_GET['download'] – число. Продолжаем выполнение.
Проверяем, есть ли в нашей БД данные об этом файле.
$query=mysql_result(mysql_query("SELECT count(0) FROM film WHERE id='{$_GET['download']}'"),0);
Если if (empty($query)) – вернул ноль, выводим ошибку.
echo"< table width="40%" align="center" cellpadding="0" cellspasing="0" class="table">< tr>< td class="er"> Фильм который вы пытаетесь скачать, не найден в нашем архиве. < /td>< /tr>< /table>";
Если, нет ошибок начинаем генерацию ссылки.
Создаём массив символов.
$tekens=array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z");
пропускаем массив через цикл и случайным образом выбираем нужно нам количество символов.
for($c = 0; $c < 36; $c++){ srand((double)microtime() * 100000000000000); $pass = $tekens[rand(0, 62)]; $code = $code.$pass; }
Где $c < 36 – это количество проходов. Т.е. наша ссылка будет содержать 36 символов, выбранных случайным образом.
$pass = $tekens[rand(0, 62)]; - Указывам выборку, от (0 до 62), так как наш массив содержит 62 символа.
Сохраняем наши данные в переменную $code, $code = $code.$pass;
Заносим информацию в БД :
mysql_query("INSERT INTO download (f_id,links,data_start) VALUES ('{$_GET['download']}','{$code}','".time()."')") or die(mysql_error());
И выводим ссылку на экран.
echo"< table width="50%" align="center" cellpadding="0" cellspasing="0" class="table">< tr>< td>Для загрузки фильма пройдите по следующей ссылке.< BR>< br>< a href="{$url}/downloads/{$code}/film/{$_GET['film']}"> {$url}/downloads/{$code}/film/{$_GET['film']} < /a>< BR>< BR>Напоминаем, ссылка действительна в течении 3-х дней.< /td>< /tr>< /table>";
Вот полный код файла. index.php
< ?php include("config.php"); if (isset($_GET['download'])) { if (!is_numeric($_GET['download'])) { echo"< span class="er">Хакер?? Хе-хе!!!< /span>< /BODY>< /HTML>";exit();} $query=mysql_result(mysql_query("SELECT count(0) FROM film WHERE id='{$_GET['download']}'"),0); if (!empty($query)) { $tekens=array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"); for($c = 0; $c < 36; $c++){ srand((double)microtime() * 100000000000000); $pass = $tekens[rand(0, 62)]; $code = $code.$pass; } mysql_query("INSERT INTO download (f_id,links,data_start) VALUES ('{$_GET['download']}','{$code}','".time()."')") or die(mysql_error()); echo"< table width="50%" align="center" cellpadding="0" cellspasing="0" class="table">< tr>< td>Для загрузки фильма пройдите по следующей ссылке.< BR>< br>< a href="{$url}/downloads/{$code}/film/{$_GET['film']}"> {$url}/downloads/{$code}/film/{$_GET['film']} < /a>< BR>< BR>Напоминаем, ссылка действительна в течении 3-х дней.< /td>< /tr>< /table>"; } else { echo"< table width="40%" align="center" cellpadding="0" cellspasing="0" class="table">< tr>< td class="er"> Фильм который вы пытаетесь скачать, не найден в нашем архиве. < /td>< /tr>< /table>"; } echo"< /BODY>< /HTML>"; exit; } $query=mysql_query("SELECT * FROM film ORDER BY date DESC") or die (mysql_error()); while($rows=mysql_fetch_array($query)) { $date = date("d-m-Y h:i:s", strtotime($rows['date'])); echo"< table width="80%" align="center" cellpadding="0" cellspasing="0" class="table"> < tr>< td wid>Название : < b>{$rows['name']}< /b>< br> Дата добавления : < b>{$date}< /b> < /td>< td align="right">< a href="index.php?download={$rows['id']}&film={$rows['file_name']}"> Скачать < /a> Размер файла : < b>{$rows['size']}< /b>< /td>< /tr> < tr>< td colspan="2" class="content">Жанр : < b>{$rows['genre']}< /b>< BR>< BR>{$rows['description']}< BR>< BR>< p align="right">Добавил : < b>{$rows['author']}< /b>< /p>< /td>< /tr> < /table>< BR>"; } mysql_close(); ?>
Если вы заметили, сама ссылка будет обрабатывается при помощи модуля Апача mod_rewrite
Наша ссылка указывает на каталог downloads, по этому создайте его.
Здесь у нас 2 файла.
index.php
.htaccess
В .htaccess указываем данные для mod_rewrite.
Вот код.
RewriteEngine On RewriteBase /test/link/downloads RewriteRule ^([A-Za-z0-9]+)/([A-Za-z]+)/(.*)$ index.php?id=$1&kat=$2&n=$3 [L]
Теперь давайте рассмотрим код файла. index.php
Первой строкой подключаем наш файл config.php
include("config.php"); $timestamp=time(); // Получаем текущее время. $timeout=$timestamp-$time_end; // Отнимаем время жизни от текущего времени.
Если вы не помните $time_end – хранится в файле config.php
mysql_query("DELETE FROM download WHERE data_start< $timeout") or die(mysql_error());
Удаляем все ссылки, которые отжили своё.
И теперь начинаем выборку из таблиц.
$query=mysql_query("SELECT a.f_id,a.id,b.file_name,b.size,b.mime_tip FROM download AS a INNER JOIN film AS b ON a.links='{$_GET['id']}' AND a.f_id=b.id") or die (mysql_error()); //Производим выборку $result=mysql_num_rows($query); // Получаем количество записей.
Если empty($result) = 0. показываем ошибку.
echo"Ваша ссылка не действительна.";
Если всё ок, делаем выборку.
$rows=mysql_fetch_array($query);
Формируем нашу ссылку:
$fpath="{$url}/{$downloads}/{$rows['file_name']}";
Получаем имя файла их $fpath.
$file = basename($fpath);
Отправляем заголовки клиенту, расскажу об основных заголовках.
header("Cache-Control: "); header("Pragma: "); header('Expires: 0'); header("Content-type: ".$rows['mime_tip']); Header("Accept-Ranges: bytes"); Header("Content-Length: ".$rows['size']); header("Content-Disposition: attachment; filename=".$file); $fdl = fopen($fpath, "r"); fpassthru($fdl); fclose($fdl); header ("Connection: close");
Указываем тип загружаемого файла. Статью о mime типах можете почитать здесь Что такое MIME типы файлов.
header("Content-type: ".$rows['mime_tip']);
Сообщаем что размер файла мы передаём в байтах.
Header("Accept-Ranges: bytes");
Что собственно и делаем.
Header("Content-Length: ".$rows['size']);
Сообщаем имя вложения.
header("Content-Disposition: attachment; filename=".$file);
Данные о файле мы получили из таблицы film
Вот полный код файла index.php
< ?php include("../config.php"); $timestamp=time(); $timeout=$timestamp-$time_end; mysql_query("DELETE FROM download WHERE data_start< $timeout") or die(mysql_error()); $query=mysql_query("SELECT a.f_id,a.id,b.file_name FROM download AS a INNER JOIN film AS b ON a.links='{$_GET['id']}' AND a.f_id=b.id") or die (mysql_error()); $result=mysql_num_rows($query); if (!empty($result)) { $rows=mysql_fetch_array($query); $fpath="{$url}/{$downloads}/{$rows['file_name']}"; $file = basename($fpath); header("Cache-Control: "); header("Pragma: "); header('Expires: 0'); header("Content-type: application/force-download"); Header("Accept-Ranges: bytes"); Header("Content-Length: 8470528"); header("Content-Disposition: attachment; filename=".$file); $fdl = fopen($fpath, "r"); fpassthru($fdl); fclose($fdl); header ("Connection: close"); } else { echo"Ваша ссылка не действительна."; } ?>
Если вы хотите отделаться от модуля mod_rewrite, первым делом удалите файл .htaccess из каталога downloads.
Переделайте ссылку из.
< a href="{$url}/downloads/{$code}/film/{$_GET['film']}"> {$url}/downloads/{$code}/film/{$_GET['film']} < /a>
на
< a href="{$url}/downloads/?id={$code}&kat=film&n={$_GET['film']}"> {$url}/downloads/?id={$code}&kat=film&n={$_GET['film']} < /a>
На самом деле, /film/ - это так, налил воды, если вы понимаете о чём я .)
А вот {$_GET['film']} – сообщает тому же FlashGET во что переименовать загружаемый файл.
Защитить ваши каталоги от просмотра, вы можете с помощью .htaccess, положите в корневой каталог скрипта такой файл со следующим кодом.
Options –Indexes
Ну вот и всё.
Постоянные ссылки
При копировании ссылка на TeaM RSN обязательна!
Оставить комментарий
Вы должны войти, чтобы оставить комментарий.