Как узнать сколько раз скачали файл?

Допустим, у вас на сайте есть раздел Downloads, где посетитель может скачать скрипты, музыку, фотографии и т.п. Но как узнать, какие файлы пользуются успехом, а какие лежат мертвым грузом (и их можно безболезненно удалить, чтобы не занимали место)?

Как решить эту проблему? Выход - счетчик скачиваний. Вы наверняка уже их видели. Обычно этот счетчик устанавливается рядом со ссылкой на скачиваемый документ. Примерно, все выглядит так:

Ссылка – Скачали [57]

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

<?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

<?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 );
?>

Комментариев: 8

  1. voral:

    Если у посетителя стоит, например, DownloadMaster то счетчик будет увеличиваться на 2…

  2. admin:

    voral, как я понимаю, DownloadMaster поддерживает закачку в несколько потоков. Поэтому счетчик увеличиваться на два (три, четыре).

  3. CharnaD:

    Как отметили предыдущие комментаторы счетчик будет увеличиваться при каждом запросе, поэтому стоит ввести проверку по IP. Но как урок - хорошо.

  4. Vanilla:

    Блин,а не на PHP никак?
    допустим если хостинг бесплатный,без поддержки PHP?

  5. admin:

    Vanilla, боюсь, что никак.

  6. Panthera-IT:

    Если я неошибаюсь,

    на второй строчке кавычку забыл.

    Так сейчас:
    if ( !isset( $_GET['id'] ) {
    а мне кажется должно быть так:
    if ( !isset( $_GET['id'] )) {

    Или я ошибаюсь?

  7. admin:

    Panthera-IT, спасибо, исправил.

  8. Игорь:

    здоров… берем id перебираем от 0..1000 и скачиваем все файлы которые есть на сервере. Стоит задуматься о конфиденциальности файлов.

Оставьте свой отзыв