Интернет, компьютеры, софт и прочий Hi-Tech

Подписаться через RSS2Email.ru

PHP — защита скачиваемых файлов

Хотите предотвратить установку ссылок на файлы для скачивания? Данный сценарий будет загружать страницу перед скачиванием файла. Оператор HTTP-заголовка начинает загрузку файла. PHP используется для передачи файла.

Принцип работы

HTTP-заголовки должны быть отправлены перед каким-либо выводом данных в браузер. PHP использует функцию header для передачи сырых HTTP-заголовков. В этом примере мы собираемся получить имя файла из URL

http://www.yourdomain.com/download.php?file=download.zip
<?
$dir="/path/to/file/";
if (isset($_REQUEST["file"])) {
    $file=$dir.$_REQUEST["file"];
    header("Content-type: application/force-download");
    header("Content-Transfer-Encoding: Binary");
    header("Content-length: ".filesize($file));
    header("Content-disposition: attachment; filename=\"".basename($file)."\"");
    readfile("$file");
} else {
    echo "No file selected";
}
?>

Мы начали с установки каталога, в котором будут находиться файлы для загрузки в $dir. Затем проверяем, что имя файла указано в запросе. Если файл был задан, то присваиваем переменной $file путь к файлу и имя файла. Теперь, когда приготовительная работа выполнена, пришло время отправить файл в браузер.

Оператор header указывает браузеру ожидать загрузки. Следующие два оператора header указывают браузеру формат данных и размер файла соответственно. Последний оператор header указывает браузеру имя файла. Наконец, оператор readfile отправляет файл в браузер.

Отслеживание загрузки файлов с помощью MySQL

Данный метод можно использовать для записи информации о загрузках файлов. В данном примере я буду отслеживать количество загрузок файлов и время последней загрузки. Эту информацию мы будем хранить в базе данных MySQL. Далее приведена структура таблицы.

CREATE TABLE filestats (
   fileid INT NOT NULL auto_increment,
   filename TEXT,
   downloads INT NOT NULL,
   lastdownload DATETIME,
   primary key (fileid)
);

Поле fileid — это автоматически увеличивающееся число, которое нужно для учета записей в базе данных. С помощью поля filename мы будем выполнять поиск. Поля downloads и lastdownload используются для ведения статистики.

Вставьте следующий код после оператора if (isset($_REQUEST["file"])) {. Данный код будет соединяться с базой данных MySQL и обновлять статистику файлов.

<?
$db=mysql_connect($mysql_host,$mysql_login,$mysql_passwd) or die(mysql_error());
mysql_select_db($mysql_database);
$query=mysql_query("select * from filestats
                    where filename='".basename($file)."' LIMIT 0,1")
       or die (mysql_error());
$fileexist=@mysql_num_rows($query));
$now=date("Y-m-d G:i:s");
if ($fileexist>0) {
    $updatequery=mysql_query("update filestats set downloads=downloads+1,
                              lastdownload='$now'
                              where filename='".basename($file)."'")
                 or die (mysql_error());
} else {
    $addquery=mysql_query("insert into filestats
                           (filename,downloads,lastdownload)
                           values ('".basename($file)."','1','$now')")
              or die (mysql_error());
} 
?>

Функция date используется для установки текущей даты и времени. Дата будет отображена в MySQL формате YYYY-MM-DD HH:MM:SS.

В данном блоке кода мы подключаемся к базе данных и обновляем статистику скачивания файлов.

Сначала mysql_connect подключается к базе данных, передавая параметры соединения по порядку: хост, логин и пароль. Затем выбираем нужную базу данных MySQL с помощью оператора mysql_select_db.

После того, как соединение установлено, мы проверяем, что в таблице есть запись для файла. Первый вызов функции mysql_query выполняет поиск записи с именем загружаемого файла в базе данных. Функция mysql_num_rows определяет количество результатов, возвращаемых запросом. Здесь перед вызовом mysql_num_rows ставим @, чтобы предотвратить вывод ошибки, если результаты запроса будут пусты.

Переменная $fileexist будет больше 0, если запись уже есть в базе данных, поэтому будем использовать MySQL запрос на обновление. Если запрос не возвращает записей, то выполним запрос на вставку.

Другие способы применения

Другие способы применения данного метода включают загрузку контента, для которого требуется подписка.

Для этого заключите код в блок для проверки учетных данных. Это легко сделать с помощью оператора if(<credentials check>) { с размещённым внутри кодом для проверки. Популярным способом хранения учетных данных является использование базы данных MySQL и предоставление сессий или cookie пользователям, которые ввели правильные учетные данные. Эти методы обеспечивают простую безопасность для продажи электронных книг, скачиваемых программ и т.д.

Автор: deuteride, специально для xBB.uz, 17.08.2011

P.S. от редактора. Хочу предупредить читателя от бездумного копирования продемонстрированного в статье кода в код рабочих проектов, поскольку автор не включил в свой код защиту от SQL-инъекций и загрузки не предназначенных для этого файлов. Это было сделано для того, чтобы не ухудшать читабельность кода для новичков. Кроме того, при внимательном чтении можно заметить, что приведенный в статье код можно оптимизировать.


Предыдущие публикации:

Биржа долевых инвестиций SIMEX.

Последнее редактирование: 2011-08-17 10:51:55

Метки материала: php, защита, файл, php защита, защита скачиваемых файлов, www, интернет, веб, it, web, internet, скрипты, программирование, информационные технологии, ит, разработка по, инет, сайт своими руками, интернет и www, сайт своими силами


2 комментария

18.08.2011 10:40:15 #
Mozilla Firefox dima
И еще один - большие файлы (например видео) таким способом нельзя отдавать - скрипт будет вылетать с ошибкой. На мой взгляд, лучше создавать симлинк на скачиваемый файл, редиректить юзера на этот симлинк, а через некоторое время, достаточное для загрузки, симлинк удалять.
17.08.2011 16:20:40 #
Google Chrome Гость llektor
Еще один минус - докачка не поддерживается

Оставьте, пожалуйста, свой комментарий к публикации

Представиться как     Антибот:
   

Просьба не постить мусор. Если вы хотите потестить xBB, воспользуйтесь кнопкой предварительного просмотра на панели инструментов xBBEditor-а.


© 2007-2017, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.