- Похожий скрипт: сбор статистики кликов по ссылке/кнопке на PHP
На ряде сайтов можно увидеть ссылку, а рядом надпись "То-то скачено столько-то раз". Или свою кнопку "Нравится" со счётчиком. Или пару "Нравится/Не нравится". Реализуются они подобным образом:
- Число нажатий хранится в базе данных (или отдельном файле). При загрузке браузером HTML-страницы оно подставляется в указанное в шаблоне место.
- Когда посетитель нажимает на кнопку на HTML-странице, JavaScript передаёт в PHP с какой страницы произошёл клик по кнопке.
- PHP меняет значение, записанное в базе данных. И передаёт число, увеличенное на единицу, в JavaScript.
- JavaScript меняет число на счётчике без перезагрузки HTML-страницы.
Ниже представлен упрощённый вариант (без подключения БД).
Файл 1.html
<a href="#" id="like">Файл [скачено <output id="statlike">0</output> раз]</a> <script> document.getElementById('like').addEventListener('click', function(e){ if (window.XMLHttpRequest && localStorage.getItem('like') != location.pathname) { e.preventDefault(); // по ссылке нельзя перейти, перенаправление осуществляется с помощьюlocation
в событииloadend
var http = new XMLHttpRequest(), href = this.href; http.open('POST', 'stat.php'); // совет: заменить на абсолютный адрес, например,http://сайт.ru/stat.php
http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); http.addEventListener('readystatechange', function() { if (this.readyState == 4 && this.status == 200) { document.getElementById('statlike').innerHTML = this.responseText; // изменить число в тегеoutput
, после того, как запрос будет исполнен } }); http.timeout = 10000; // прервать запрос, если он длиться более 10 секунд http.addEventListener('loadend', function() { location = href }); http.send('url=' + location.pathname); // передать в POST запросе адрес файла, который нужно изменить localStorage.setItem('like', location.pathname); // запись в локальное хранилище о том, что был сделан клик (более надёжно отслеживать cookie авторизованных пользователей) } }); </script>
Файл stat.php
<?php if (isset ($_POST['url'])) { // если переменная установлена (передана) $fn = $_SERVER['DOCUMENT_ROOT'] . $_POST['url']; // абсолютный адрес файла if (file_exists($fn)) { // если файл существует $f = fopen($fn, "r+"); // открыть файл if (flock($f, LOCK_EX)) { // заблокировать файл, пока выполняется скрипт [php.net] $fr = fread($f, filesize($fn)); // записать в переменную содержимое файла $pattern = '/(<output id="statlike">)(\d+)(<\/output>)/i'; $line_ok = preg_match($pattern, $fr, $matches); if($line_ok == 1) { // если в содержимом был найден тегoutput
сid="statlike"
$m = $matches[2] + 1; // к числу прибавить 1 $fr = preg_replace($pattern, '${1}'.$m.'$3', $fr, 1); // изменить число в содержимом rewind($f); // переместить указатель в начало файла ftruncate($f, 0); // очистить файл fwrite($f, $fr); // записать в файл содержимое с изменённым числом } echo $m; // вывести число, чтобы передать в JS flock($f, LOCK_UN); // разблокировать файл } fclose($f); // закрыть файл } } ?>
Внимание: пример демонстрирует работу JS. PHP всё же должен менять базу данных, так как при использовании предложенного варианта могут возникнуть сложности при одновременном доступе к файлу (см. про flock).
4 комментария: