Создаем счетчик загрузок файла с помощью PHP и MySQL. Устанавливаем счетчик скачиваний — обзор плагинов для Вордпресс Выезжающая панель на «Mootools»

Давно уже не было уроков про PHP и MySQL. Сегодня мы создадим простой, но эффективный счетчик скачиваний.

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

Для отслеживания количества скачиваний любого файла, Вам необходимо его положить в папку files и использовать специальный УРЛ для обращения к нему.

Шаг 1 - XHTML

Первым шаг - это создание разметки нашего скрипта. Она очень простая - у нас есть div file-manager, который содержит неупорядоченный список, в котором каждый элемент списка отвечает за файл.

Файлы, скачивания которых необходимо отследить, помещены в папку files в корневой папке скрипта. PHP потом проходит по всем файлам и добавляет каждый в качестве элемента списка (li) в неупорядоченный список.

demo.php


  • photoShoot-1.0.zip 0 download

Обратите внимание, что атрибут 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 "

  • ".$val." ".(int)$file_downloads[$val]." download
  • "; }

    Все делается просто с помощью цикла 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.

    ForceType application/octet-stream

    Вот теперь наш счетчик полностью готов!

    Заключение

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

    После этого, добавьте Ваши данные для соединения с БД в файле configuration.php.

    Решил посмотреть сколько раз скачивают один из моих скриптов с сайта. Для этого решил написать счётчик скачиваний файлов для сайта. В интернете много реализаций данной задачи, но тем неменее ознакомтесь с моим решением.

    Логика работы счётчика скачивания довольна проста. Для его реализации будем использовать мой любимый ajax. Вешаем на кнопку при возникновении событи clik обращение через ajax к php файлу счётчика. В php происходит обработка ajax запроса и запись в текстовый файл цифры суммарного количества скачек. После удачной записи возвращается ответ с суммарным счётчиком скачиваний и происходит редирект пользователя на ссылку для скачки файла (файл скачивается). Вот такая вот простая логика Теперь начнём её реализовать. Заранее создадим скачиваемый файл test.zip . Сделаем код кнопки и покажем счётчик скачек.

    Скачать файл Количество скачек:

    Мы создали кнопку с id="btnSend" , выводить счётчик будем в span с id="countView" , в атрибуте data-download будем хранить ссылку на скачиваемый файл

    Теперь давайте прикрутим к кнопке обработчик клика. Здесь уже будем использовать js и jquery. Про то как реализовать clik силами jquery можно почитать . Но перед установкой обработчика клика мы будем ajax обращаться к файлу count.php, в котором будет заключена вся работа счётчика. Подробнее о передаче данных ajax можно почитать . Это нужно что бы вывести из файла куда пишет счётчик, количество уже сделанных закачек и вывести их в span с id="countView"

    /*получаем текущее кол-во закачек*/ $(document).ready(function(){ //запрещаем кещировать ajax запрос //иначе счётчик будет брехать $.ajaxSetup({cache: false}); var html; $.ajax({ //как будем передавать данные type: "GET", //куда передаём url: "count.php", //какие данные передаём data: {flag: 2}, //событие после получения ответа от count.php success: function(data){ html=data; //выводим текущее кол-во закачек $("#countView").html(html); } }); /*вешаем событие на кнопку скачать файл*/ var clickevent=false;//флаг проверки нажатия //обработчик клика $("#btnSend").click(function(){ if(!clickevent){ $.ajax({ //как будем передавать данные type: "GET", //куда передаём url: "count.php", //какие данные передаём data: {flag: 1}, //событие перед отправкой ajax beforeSend: function(){ //если кнопка была нажата то труе clickevent=true; }, //событие после получения ответа, //получаем данные в data success: function(data){ //после выполнения действий разрешаем опять //обрабатывать клик по кнопке clickevent=false; html=data; //выводим новый счётчик $("#countView").html(html); //получаем ссылку из data-download //редиректит по ссылке скачки, качаем файл window.location.href = $("#btnSend").data("download"); } }); } return false;//запрещаем обрабатывать событие при клике }); });

    Для предотвращения повторного ошибочного нажатия кнопки отправки я ввёл в скрипт флаг clickevent . Пока не вернётся ответ от count.php с обновившимися данными счётчика клик по кнопке будет запрещён. Я так думаю работа кода после клика по кнопке более менее ясна. После клика по кнопке скачать в файл count.php передаются данные, там они обрабатываются и возвращается обновлённые данные счётчика, происходит редирект на ссылку скачивания и соответственно сама закачка файла.

    Давайте теперь разберём сердце нашего скрипта, а именно файл count.php.

    Function clearInt ($date){ //приводим date к числу, не отрицательному return abs((int)$date); } if($_SERVER["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest") { //проверяем какой флаг пришёл if(clearInt($_GET["flag"]==1)) { //открываем файл для чтения $f=fopen("mycount.txt","a+"); //закрывает доступ к файлу из других программ flock($f,LOCK_EX); //получаем из файла значение счётчика $count=fread($f,100); //плюсуем счётчик @$count++; //затираем файл ftruncate($f,0); //пищем новое покакзание счётчика fwrite($f,$count); //закрываем файл fclose($f); //возвращаем значение echo $count; } if(clearInt($_GET["flag"]==2)) { $c=fopen("mycount.txt","a+"); flock($c,LOCK_EX); $festc=fread($c,100); fclose($c); //возвращаем значение echo $festc; } }

    Здесь я то же думаю всё просто. Если приходит флаг 1 то делаем перезапись счётчика. Если приходит флаг 2 то просто возвращаются данные о количестве закачек. Всё остальное я думаю понятно из комментариев в коде.

    Cчетчик скачиваний Joomla

    Решил прикрутить подобный счётчик на один из моих проектов на joomla. По идее нужно конечно написать либо отдельный модуль, либо интегрировать код в контроллер компонента com content, что бы данные счётчика писались не в файл, а в бд и для каждой статьи отдельно. Но на на такую разработку нет времени и я решил вопрос более просто. Счётчик мне был нужен для одной страницы. Я взял файл count.php и перенёс его в шаблон джумла, который на данный момент подключён (в корне сайта templates/ваш_шаблон). Не забываем вставить в самый верх count.php код defined("_JEXEC") or die; (это для джумла). Кнопку закачки вставляем в создаваемую нами страницу, а js код можно так же встроить в страницу, либо подключить отдельным файлом. У меня например отдельным файлом (он находится в папке js шаблона). В самом шаблоне в хедере происходит подключение через код