Как узнать сколько раз скачали файл?
Допустим, у вас на сайте есть раздел Downloads, где посетитель может скачать скрипты, музыку, фотографии и т.п. Но как узнать, какие файлы пользуются успехом, а какие лежат мертвым грузом (и их можно безболезненно удалить, чтобы не занимали место)?
Как решить эту проблему? Выход - счетчик скачиваний. Вы наверняка уже их видели. Обычно этот счетчик устанавливается рядом со ссылкой на скачиваемый документ. Примерно, все выглядит так:
57 – это число, которое увеличивается на 1 при каждом скачивании файла.
Пусть информация о файлах для скачивания у нас хранится в таблице базы данных, которая имеет следующую структуру:
- id - уникальный ID файла
- title - название программы, например, “Текстовой редактор NotePad++“
- about - краткое описание программы, например, “Бесплатный редактор текстовых файлов (замена стандартного Блокнота) с поддержкой синтаксиса большого количества языков программирования, ориентирован для работы в операционной системе MS Windows“
- name - имя файла для скачивания, например, NotePadPP.zip
- download - количество скачиваний
Вообще говоря, файлы можно просто хранить под именами 1.zip, 2.zip, 3.zip, где 1, 2, 3 - уникальные ID. Потому как в поле name особого смысла нет - это избыточная информация. Единственная польза от такого поля - это при скачивании отдавать файл с каким-нибудь осмысленным именем, т.е. NotePadPP.zip, а не 1.zip.
Все файлы для скачивания лежат в директории
DOCUMENT_ROOT/downloads
В этой же директории лежит файл index.php, который выводит список всех файлов, доступных для скачивания и файл download.php, который отдает файлы на скачивание.
Файл index.php
$query = "SELECT id, name, about, download FROM programs WHERE 1";
$res = mysql_query( $query );
echo '<table border="1">';
while( $row = mysql_fetch_array( $res ) ) {
echo '<tr>';
echo '<td>'.$row['name'].'</td>';
echo '<td>'.$row['about'].'</td>';
echo '<td><a href="/downloads/download.php?id='.$row['id'].'" target="_blank">Скачать</td>';
echo '<td>Скачан '.$row['downloads'].' раз</td>';
echo '</tr>';
}
echo '</table>';
?>
Файл download.php
if ( !isset( $_GET['id'] ) ) {
// если не передан ID файла
header ("HTTP/1.0 404 Not Found");
die();
}
$id = (int)$_GET['id'];
if ( $id < 1 ) {
header ("HTTP/1.0 404 Not Found");
die();
}
// Узнаем имя файла для скачивания
$query = "SELECT name FROM programs WHERE id=".$id;
$res = mysql_query( $query );
if ( mysql_num_rows( $res ) == 0 ) {
header ("HTTP/1.0 404 Not Found");
die();
}
$filename = mysql_result( $res, 0, 0 );
// если файла нет
if (!file_exists($filename)) {
header ("HTTP/1.0 404 Not Found");
die();
}
// сообщаем размер файла
header( 'Content-Length: '.filesize($filename) );
// дата модификации файла для кеширования
header( 'Last-Modified: '.date("D, d M Y H:i:s T", filemtime($filename)) );
// сообщаем тип данных - zip-архив
header('Content-type: application/zip');
// файл будет получен с именем $filename
header('Content-Disposition: attachment; filename="'.$filename.'"');
// начинаем передачу содержимого файла
readfile($filename);
// Увеличиваем счетчик количества закачек
mysql_query( "UPDATE programs SET download=download+1 WHERE id=".$id );
?>
voral:
Если у посетителя стоит, например, DownloadMaster то счетчик будет увеличиваться на 2…
2 Декабрь 2008, 13:31admin:
voral, как я понимаю, DownloadMaster поддерживает закачку в несколько потоков. Поэтому счетчик увеличиваться на два (три, четыре).
3 Декабрь 2008, 11:58CharnaD:
Как отметили предыдущие комментаторы счетчик будет увеличиваться при каждом запросе, поэтому стоит ввести проверку по IP. Но как урок - хорошо.
7 Декабрь 2008, 3:21Vanilla:
Блин,а не на PHP никак?
28 Декабрь 2008, 17:53допустим если хостинг бесплатный,без поддержки PHP?
admin:
Vanilla, боюсь, что никак.
29 Декабрь 2008, 13:29Panthera-IT:
Если я неошибаюсь,
на второй строчке кавычку забыл.
Так сейчас:
if ( !isset( $_GET['id'] ) {
а мне кажется должно быть так:
if ( !isset( $_GET['id'] )) {
Или я ошибаюсь?
31 Май 2009, 13:43admin:
Panthera-IT, спасибо, исправил.
31 Май 2009, 14:30Игорь:
здоров… берем id перебираем от 0..1000 и скачиваем все файлы которые есть на сервере. Стоит задуматься о конфиденциальности файлов.
24 Июнь 2010, 10:38