PHP + MySQL счетчик скачиваний


Давно уже не было уроков про PHP и MySQL. Сегодня мы создадим простой, но эффективный счетчик скачиваний. У каждого файла будет запись в ряду таблицы базы данных. В этой же таблице будет сохраняться количество скачиваний файла. PHP будет обновлять БД MySQL и перенаправлять пользователя на необходимый файл. Для отслеживания количества скачиваний любого файла, Вам необходимо его положить в папку files и использовать специальный УРЛ для обращения к нему. Шаг 1 - XHTML Первым шаг - это создание разметки нашего скрипта. Она очень простая - у нас есть div file-manager, который содержит неупорядоченный список, в котором каждый элемент списка отвечает за файл. Файлы, скачивания которых необходимо отследить, помещены в папку files в корневой папке скрипта. PHP потом проходит по всем файлам и добавляет каждый в качестве элемента списка (li) в неупорядоченный список. demo.php <div id="file-manager"> <ul class="manager"> <!-- Элементы LI сгенерированные php --> <li><a href="download.php?file=photoShoot-1.0.zip">photoShoot-1.0.zip <span class="download-count" title="Times Downloaded">0</span> <span class="download-label">download</span></a> </li> </ul> </div> Обратите внимание, что атрибут href ссылок передает название файла в качестве параметра для download.php. именно здесь и происходит отслеживание количества скачиваний. Вам необязательно отображать все таким же образом - Вы просто можете давать ссылки на download.php на Ваших страницах и все скачивания не пройдут мимо. Шаг 2 - CSS После разметки давайте займемся оформлением. CSS правила ниже обращаются к div file-manager с помощью id (символ #), так как он встречается только 1 раз на странице, и к остальным элементам по названиям классов. styles.css #file-manager{ background-color:#EEE; border:1px solid #DDD; margin:50px auto; padding:10px; width:400px; } ul.manager li{ background:url("img/bg_gradient.gif") repeat-x center bottom #F5F5F5; border:1px solid #DDD; border-top-color:#FFF; list-style:none; position:relative; } ul.manager li a{ display:block; padding:8px; } ul.manager li a:hover .download-label{ /* При наведении на мпимок, показать зеленый текст скачать: */ display:block; } span.download-label{ background-color:#64B126; border:1px solid #4E9416; color:white; display:none; font-size:10px; padding:2px 4px; position:absolute; right:8px; text-decoration:none; text-shadow:0 0 1px #315D0D; top:6px; /* CSS3 Закругленные углы */ -moz-border-radius:3px; -webkit-border-radius:3px; border-radius:3px; } span.download-count{ color:#999; font-size:10px; padding:3px 5px; position:absolute; text-decoration:none; } Шаг 3 - PHP Как я говорил раньше, PHP ищет файлы в папке files и выводит каждый файл в качестве элемента списка в неупорядоченном списке. Давайте взглянем на то, как это происходит demo.php - верхняя часть // Сообщение об ошибках: error_reporting(E_ALL^E_NOTICE); // Включаем файл подключения к ДБ: require 'connect.php'; $extension=''; $files_array = array(); /* Открываем папку и проходим по всем файлам: */ $dir_handle = @opendir($directory) or die("There is an error with your file directory!"); while ($file = readdir($dir_handle)) { /* Пропускаем системные файлы: */ if($file{0}=='.') continue; /* end() выводит последний элемент массива сгенерированного функцией explode(): */ $extension = strtolower(end(explode('.',$file))); /* Пропускаем php файлы: */ if($extension == 'php') continue; $files_array[]=$file; } /* Сортируем файлы в алфавитном порядке */ sort($files_array,SORT_STRING); $file_downloads=array(); $result = mysql_query("SELECT * FROM download_manager"); if(mysql_num_rows($result)) while($row=mysql_fetch_assoc($result)) { /* Ключ массива $file_downloads будет названием файла, и будет содержать кол-во скачиваний: */ $file_downloads[$row['filename']]=$row['downloads']; } Обратите внимание как мы выбираем все ряды с таблицы download_manager с помощью mysql_query(), и позже добавляем их к массиву $file_downloads с названием файла в качестве ключа к количеству скачиваний. Таким образом, далее в коде, мы можем писать $file_downloads['archive.zip'] и выводить количество скачиваний. Ниже Вы видите код, который генерирует элементы списка: demo.php - средняя часть foreach($files_array as $key=>$val) { echo '<li><a href="download.php?file='.urlencode($val).'">'.$val.' <span class="download-count" title="Times Downloaded">'.(int)$file_downloads[$val].'</span> <span class="download-label">download</span></a> </li>'; } Все делается просто с помощью цикла foreach массива $files_array. После этого все выводится с помощью echo. Теперь давайте более детально взглянем на то, как происходит отслеживание файлов. download.php // Проверка ошибок: error_reporting(E_ALL^E_NOTICE); // Включаем файл подключения к ДБ: require('connect.php'); if(!$_GET['file']) error('Missing parameter!'); if($_GET['file']{0}=='.') error('Wrong file!'); if(file_exists($directory.'/'.$_GET['file'])) { /* Если посетитель не поисковой бот, засчитываем скачивание: */ if(!is_bot()) mysql_query(" INSERT INTO download_manager SET filename='".mysql_real_escape_string($_GET['file'])."' ON DUPLICATE KEY UPDATE downloads=downloads+1"); header("Location: ".$directory."/".$_GET['file']); exit; } else error("This file does not exist!"); /* функции помощники: */ function error($str) { die($str); } function is_bot() { /* Эта функция проверки на робота */ $botlist = array("Teoma", "alexa", "froogle", "Gigabot", "inktomi", "looksmart", "URL_Spider_SQL", "Firefly", "NationalDirectory", "Ask Jeeves", "TECNOSEEK", "InfoSeek", "WebFindBot", "girafabot", "crawler", "www.galaxy.com", "Googlebot", "Scooter", "Slurp", "msnbot", "appie", "FAST", "WebBug", "Spade", "ZyBorg", "rabaz", "Baiduspider", "Feedfetcher-Google", "TechnoratiSnoop", "Rankivabot", "Mediapartners-Google", "Sogou web spider", "WebAlta Crawler","TweetmemeBot", "Butterfly","Twitturls","Me.dium","Twiceler"); foreach($botlist as $bot) { if(strpos($_SERVER['HTTP_USER_AGENT'],$bot)!==false) return true; // Is a bot } return false; // Not a bot } Важно проверить является ли Ваш посетитель человек или роботом поисковиков. Роботы это конечно хорошо, но не позволим им искажать нашу статистику. Именно поэтому ряд в базе данных обновляется только после проверки is_bot(). Шаг 4 - MySQL Как мы заметили в прошлом шаге, количество скачиваний сохраняется в качестве ряда в таблице download_manager. Для начала давайте объясним как работает этот запрос: download.php INSERT INTO download_manager SET filename='filename.doc' ON DUPLICATE KEY UPDATE downloads=downloads+1 Он говорит MySQL вставить новый ряд в таблицу download_manager, и установить поле ряда filename на значение вызванного к скачиванию файла. Однако, поле filename обозначенного как уникальный индекс в таблице. Это означает, что каждый ряд можно вставлять только раз, иначе возникнет ошибка duplicate key error. Именно здесь и будет работать вторая часть запроса - ON DUPLICATE KEY UPDATE сообщит MySQL добавить единицу к колонке скачиваний, если файл уже существует в базе. Таким образом новые файлы будут автоматически добавляться в БД при первом скачивании. Шаг 5 - jQuery Для того, чтобы сделать отслеживание в виде реального времени, было бы хорошо обновлять счетчик возле названия файла после каждой загрузки. Мы это сделаем с помощью jQuery: script.js $(document).ready(function(){ /* Код выполняется после загрузки страницы */ $('ul.manager a').click(function(){ var countSpan = $('.download-count',this); countSpan.text( parseInt(countSpan.text())+1); }); }); Мы просто присваиваем обработчик кликов к ссылкам, который ведут к файлам, и при каждом нажатии мы добавляем значение. Шаг 6 - htaccess Есть еще одна вещь, которую необходимо сделать. Download.php редиректит пользователя к запрашиваемому файлу, который был передан в качестве параметра. Однако, Вы могли заметить, что некоторые типы файлов браузеры пытаются открыть напрямую. Нам же необходимо инициировать их загрузку. Это можно сделать с помощью нескольких строк внутри файла .htacess, который находится в папке files. <Files *.*> ForceType application/octet-stream </Files> Вот теперь наш счетчик полностью готов! Заключение Для того, чтобы демо заработало у Вас необходимо воссоздать таблицу download_manager в базе данных MySQL. Вы можете найти необходимый SQL код в исходниках. После этого, добавьте Ваши данные для соединения с БД в файле configuration.php.