Делаем счетчик просмотров для страницы с топиком
Вообщем решил я прикрутить к своему сайту, счетчик просмотров. А именно для страниц с топиком. Поиск по интернету дал решение, с которым я и делюсь ;)
Собственно на картинке всё видно, работает он как все стандартные счетчики, и учитывает только просмотр страницы…
И так поехали ;)
1. Нам нужно создать новую таблицу в MySQL, в которой естественно всё это дело будет храниться. Для этого запускаем phpMyAdmin → выбираем базу на которой работает сайт → на самом вверху вкладка SQL
Выполнить SQL-запрос(ы) к базе данных ХХХ_ХХХ:
CREATE TABLE `my_log` (
`page_id` varchar(32) NOT NULL default '',
`all` int(11) NOT NULL default '0',
`today` int(11) NOT NULL default '0',
`date` int(11) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
вставляем это, и жмем ОК. Через пару секунд, должно написаться что таблица my_log готова.
Теперь в нашей Базе появилась таблица my_log
* * * * *
2. Теперь нам нужно создать сам php-счетчик. Для этого создаем новый файл (текстовый документ) и называем его counter.php Кодировку ставим ANSI as UTF8 (UTF8 без BOM)
<?php
///////////////////////////////////////////
/// Скрипт статистики просмотров станиц ///
///////////////////////////////////////////
/* данные для соединения с MySQL */
$INFO['sql_host'] = "localhost";
$INFO['sql_user'] = "Пользователь_БазыДанных";
$INFO['sql_pass'] = "Пароль";
$INFO['sql_database'] = "Имя_БазыДанных";
/* проверка, есть ли запись в MySQL */
/* таблице с таким id или ее нет */
function searchID($id)
{
$result = mysql_query ("SELECT * FROM `my_log` WHERE `page_id` LIKE '".$id."'");
$num_rows = mysql_num_rows($result);
if ($num_rows>0)
{
return True;
}
else
{
return False;
}
}
/* Читает запись из MySQL таблицы */
/* возвращает ассоциированный массив */
function MySQLRead($id)
{
$id = addslashes($id);
$result = mysql_query ("SELECT * FROM `my_log` WHERE `page_id` LIKE '".$id."'");
return (array)mysql_fetch_assoc($result);
}
/* Обновление времени для конкретной записи */
function UpdateTime($id, $time)
{
$id = addslashes($id);
$time = addslashes($time);
$result = mysql_query ("UPDATE `my_log` SET `date` = '".$time."' WHERE `page_id` = '".$id."'");
return $result;
}
/* Обновление счетчиков для записи с указанным id */
function UpdateCounders($id, $all, $today)
{
$id = addslashes($id);
$time = addslashes($time);
$result = mysql_query ("UPDATE `my_log` SET `all` = '".$all."',`today` = '".$today."' WHERE `page_id` = '".$id."'");
return $result;
}
/* Запись всех значений "По умолчанию" */
function Default_Write($id)
{
$id = addslashes($id);
$result = mysql_query ("INSERT INTO `my_log` ( `page_id` , `all` , `today` , `date` ) VALUES ('".$id."' , 1 , 1 , '".(time()+60*60*24)."');");
return $result;
}
$unical_page_id_gid = md5($_SERVER['REQUEST_URI']); // получение md5() хэша из url страницы
$link = mysql_connect($INFO['sql_host'], $INFO['sql_user'], $INFO['sql_pass']); // Соединение с MySQL
mysql_select_db ($INFO['sql_database']); // Выбор базы данных
if (!searchID($unical_page_id_gid)) // существует ли запись с таким id
{
Default_Write($unical_page_id_gid); // запись всех значений по умолчанию
}
else // если не существует
{
$tmp = MySQLRead($unical_page_id_gid); // считаем значения
$all = $tmp['all'] + 1;
$today = $tmp['today'] +1;
if (time()>=$tmp['date']) // если сутки с момента записи прошли
{
UpdateTime($unical_page_id_gid, (time()+60*60*24)); // обновим дату
UpdateCounders($unical_page_id_gid, $all, 1); // обновим счетчики
define("Today_and_all_counter", "Просмотров: 1. Сегодня: 1");
}
else // если еще нет
{
/* обновим счетчики */
UpdateCounders($unical_page_id_gid, $all, $today);
}
/* устанавливаем константу с текущими значениями счетчиков */
define("Today_and_all_counter", "Просмотров: $all. Сегодня: $today");
}
mysql_close($link); // Разрываем соединение с MySQL
?>
вставляем это, и не забываем в самом начале указать данные для соединения с MySQL
База естественно та, в которой мы создали нашу новую таблицу.
Заливаем наш counter.php к себе на сайт, например в папку my_php
(тоесть чтоб файл был по адресу сайт.ру/my_php/counter.php)
* * * * *
3. Теперь нам необходимо создать файл .tpl, который мы будем подключать в наш шаблон. Для этого создаем новый файл (текстовый документ) и называем его topic_counter.php.tpl Кодировку ставим ANSI as UTF8 (UTF8 без BOM)
{php}
include('my_php/counter.php');
echo Today_and_all_counter;
{/php}
вставляем это, только не забываем указывать свой путь, если файл положили в другую папку.
Все, заливаем наш файл topic_counter.php.tpl в папку шаблона /templates/skin/new/
* * * * *
4. Вот собственно почти и всё. Нам осталось только подключить наш php-счетчик, к нашему шаблону. Топаем в /templates/skin/new/topic.tpl ~59стока
Ищем:
<ul class="voting {if $oVote || ($oUserCurrent && $oTopic->getUserId()==$oUserCurrent->getId())|| strtotime($oTopic->getDateAdd())<$smarty.now-$oConfig->GetValue('acl.vote.topic.limit_time')}{if $oTopic->getRating()>0}positive{elseif $oTopic->getRating()<0}negative{/if}{/if} {if !$oUserCurrent || $oTopic->getUserId()==$oUserCurrent->getId() || strtotime($oTopic->getDateAdd())<$smarty.now-$oConfig->GetValue('acl.vote.topic.limit_time')}guest{/if} {if $oVote} voted {if $oVote->getDirection()>0}plus{elseif $oVote->getDirection()<0}minus{/if}{/if}">
<li class="plus"><a href="#" onclick="lsVote.vote({$oTopic->getId()},this,1,'topic'); return false;"></a></li>
<li class="total" title="{$aLang.topic_vote_count}: {$oTopic->getCountVote()}">{if $oVote || ($oUserCurrent && $oTopic->getUserId()==$oUserCurrent->getId()) || strtotime($oTopic->getDateAdd())<$smarty.now-$oConfig->GetValue('acl.vote.topic.limit_time')} {if $oTopic->getRating()>0}+{/if}{$oTopic->getRating()} {else} <a href="#" onclick="lsVote.vote({$oTopic->getId()},this,0,'topic'); return false;">—</a> {/if}</li>
<li class="minus"><a href="#" onclick="lsVote.vote({$oTopic->getId()},this,-1,'topic'); return false;"></a></li>
<li class="date">{date_format date=$oTopic->getDateAdd()}</li>
if $oTopic->getType()=='link'}
<li class="link"><a href="{router page='link'}go/{$oTopic->getId()}/" title="{$aLang.topic_link_count_jump}: {$oTopic->getLinkCountJump()}">{$oTopic->getLinkUrl(true)}</a></li>
{/if}
<li class="author"><a href="{$oUser->getUserWebPath()}">{$oUser->getLogin()}</a></li>
{hook run='topic_show_info' topic=$oTopic}
</ul>
И почти в самом низу, перед {hook run='topic_show_info' topic=$oTopic} вставляем {include file='topic_counter.php.tpl'}
Должно пуличиться так:
<ul class="voting {if $oVote || ($oUserCurrent && $oTopic->getUserId()==$oUserCurrent->getId())|| strtotime($oTopic->getDateAdd())<$smarty.now-$oConfig->GetValue('acl.vote.topic.limit_time')}{if $oTopic->getRating()>0}positive{elseif $oTopic->getRating()<0}negative{/if}{/if} {if !$oUserCurrent || $oTopic->getUserId()==$oUserCurrent->getId() || strtotime($oTopic->getDateAdd())<$smarty.now-$oConfig->GetValue('acl.vote.topic.limit_time')}guest{/if} {if $oVote} voted {if $oVote->getDirection()>0}plus{elseif $oVote->getDirection()<0}minus{/if}{/if}">
<li class="plus"><a href="#" onclick="lsVote.vote({$oTopic->getId()},this,1,'topic'); return false;"></a></li>
<li class="total" title="{$aLang.topic_vote_count}: {$oTopic->getCountVote()}">{if $oVote || ($oUserCurrent && $oTopic->getUserId()==$oUserCurrent->getId()) || strtotime($oTopic->getDateAdd())<$smarty.now-$oConfig->GetValue('acl.vote.topic.limit_time')} {if $oTopic->getRating()>0}+{/if}{$oTopic->getRating()} {else} <a href="#" onclick="lsVote.vote({$oTopic->getId()},this,0,'topic'); return false;">—</a> {/if}</li>
<li class="minus"><a href="#" onclick="lsVote.vote({$oTopic->getId()},this,-1,'topic'); return false;"></a></li>
<li class="date">{date_format date=$oTopic->getDateAdd()}</li>
if $oTopic->getType()=='link'}
<li class="link"><a href="{router page='link'}go/{$oTopic->getId()}/" title="{$aLang.topic_link_count_jump}: {$oTopic->getLinkCountJump()}">{$oTopic->getLinkUrl(true)}</a></li>
{/if}
<li class="author"><a href="{$oUser->getUserWebPath()}">{$oUser->getLogin()}</a></li>
{include file='topic_counter.php.tpl'}
{hook run='topic_show_info' topic=$oTopic}
</ul>
* * * * *
По дефолту выводиться считчик типа: Всего просмотров: 100. Сегодня: 5
Если нужно только Просмотров: 100, то в самом низу в файле counter.php, удаляем ненужное:
83строка / «Просмотров: 1. Сегодня: 1» заменяем на «Просмотров: 1»
91строка / «Просмотров: $all. Сегодня: $today» заменяем на «Просмотров: $all»
* * * * *
MySQL таблицы будут занимать очень мало места, а все из-за того, что все url будут хешированны с помощью php функции md5(), что гарантирует почти 100% неповторяющихся id для каждой страницы сайта. Делается это исключительно для ускорения работы php скрипта (при условии, что индексом является id страницы) и уменьшения размеров MySQL таблицы (за счет отсутствия длинных url).
page_id – уникальный id для каждой страницы сайта сгенерированный php функцией md5().
all – значение всех просмотров данной страницы.
today – просмотров страницы сегодня.
date – дата возвращаемая php функцией time() + 24 часа
* * * * *
Счетчик учитывает абсолютно всех, без исключения. Тоесть даже поисковые роботы, буду влиять на показания.
26 комментариев
создаём файл HookTopicView.class.php
в шаблон
проще? :)
отлично работает через хук
А как теперь еще реализовать вывод топиков по просмотрам в блоке «Рейтинг публикаций», который в плагине "Дополнительные блоки"?
у меня рушит все в одной папке
Спасибо.
Если я не ошибаюсь здесь просто каждый кто защёл на топик в DB в колонке с количеством посетителей страницы, прибавляется +1..?
— dedmixei
— проще, но он добавляет единицу просмотра при каждом обновлении страницы! это не годится. как сделать привязку к ip?
Заинтересованные лица могут сделать накрутку определённой страницы — а это, как бы помягче сказать — не есть хорошо. Хочется реальных показателей т.е. подсчёт посетителя раз в сутки. Вывод: привязка по IP.
Очень жду добавления в счётчик такой фунции!
шаблон «симпл», плагин «ViewCount plugin» при активации выдает ошибку, типа не может найти php скрипт плагина