Создание счетчика посещений на Perl.
Автор: неизвестен
Редактор: Кирилл Шагин
Что ж, сегодня мы научимся создавать простейшие счётчики для личных Web-страниц.
Так как этот вопрос не раз задавался в этом журнале. Конечно, все ниже описанное
ни коим образом не посягает на идеал, хотя бы потому, что это один из первых
моих счётчиков, а может потому, что мне пока 16... не знаю, но знаю точно, что
это РАБОТАЕТ!
Итак, начнём.
Разберёмся, какие действия должен выполнять наш счётчик:
1. считать общее количество посетителей
2. считать число уникальных посетителей за день
Теперь обозначим, где будут хранится данные. Я думаю, что удобнее всего их хранить в текстовых файлах, причём таковых будет два: в первом будет храниться вся статистика (т.е. и хиты и хосты). А второй текстовый файл нам очень пригодиться для хранения базы IP. Когда посетитель будет заходить на нашу страничку впервые, то его IP занесётся в базу (чтобы его впредь больше не считать уникальным), в текстовом файле произойдут изменения: увеличатся значения хитов и хостов на 1. Теперь, допустим, тот же человек, с тем же IP заходит повторно к нам на пагу.
Перед тем, как увеличить статистику, следует порыскать в нашей базе, и если такого IP за этот день там нет, значит можно спокойно конкатенировать и то и другое, если же есть, то увеличиваем только хиты. Следует заметить, что в базе IP, кроме самих IP будут храниться дни посещения. И если любой пользователь зайдёт на сайт, допустим, через неделю, и он был единственным за это время то, следовательно база устарела и в результате из неё будут вычищены прошлые данные.
Вот собственно код:
#!/usr/local/bin/perl
# Объявляем переменные
# Получаем день и номер месяца, хотя остальное не используется
# но удалять что-либо нельзя, т.к. присвоение идёт
# в контексте списка.
my ($sec, $min, $hour, $day, $mon) = localtime(time);
# в путь к файлу гле будут IP
my $IpFile = "/shttps/WWW/COUNT/ip.txt";
# в путь к файлу где будет лежать статистика
my $CountFile = "/shttps/WWW/COUNT/count.txt";
# ваш IP
my $ip = $ENV{'REMOTE_ADDR'};
# переменная-флаг, проверяющая IP на уникальность
my $new = "true";
# эта функция используется для обновления (перезаписи)
# статистики и для добавления новых IP в базу
sub WriteBase
{
# 1 параметр - путь для записи в файл
# 2 параметр - отвечает за перезапись или добавление данных
$path = $_[0];
$bit = $_[1];
if ($bit == 2){open COUNTFILE, ">$path"}
elsif ($bit == 3){open COUNTFILE, ">>$path"}
flock(COUNTFILE); # чтобы юзвери в один файл разом не
# ломились, "блокуем" его до закрытия
# правда у меня в винде эта фича не проходит,
# но в UNIX должна, если нет - ПИШИТЕ!
# если у вас Win9x - то уберите ВЕЗДЕ её
for ($i=2; $i<=$#_; $i++)
{
print COUNTFILE "$_[$i]\n";
}
close COUNTFILE;
}
# эта функция используется для чтения данных
sub ReadBase
{
# ей нужен только 1 парам. - путь для чтения
$path = $_[0];
open COUNTFILE, "<$path";
flock(COUNTFILE)
@count = <COUNTFILE>;
close COUNTFILE;
chomp($hits = @count[0]); # читаем кол-во хитов
chomp($hosts = @count[1]); # читаем кол-во хостов
}
# здесь мы сравниваем сумму числа месяца и номер месяца текущих
# с суммой, которая была записана раннее, при чьём-нибудь
# заходе на страницу. И если прошлая запись старая, т.е.
# допустим, это был день назад, то удаляем ко всем чертям
# эти старые записи с IP, чтобы позволить в любой другой
# день пользователю быть УНИКАЛЬНЫМ! Без этой проверки
# IP хранились бы вечно (+ занимали бы место и усложняли чтение)
# и пользователь, посетив раз эту страницу
# уже не был бы уникальным НИКОГДА.
open IP, "<$IpFile";
flock(IP)
while(<IP>)
{
if (/ (\d+)/ $1<$day+$mon)
{
close IP;
unlink $IpFile; # ко всем чертям старую базу!
ReadBase($CountFile); # читаем статистику
WriteBase($CountFile, 2, $hits, 0); # сохраняем хиты, обнуляем хосты
}
}
close IP;
# проверка юзверя на уникальность
open IP, "<$IpFile";
flock(IP)
while(<IP>)
{
if (/$ip $day+$mon/)
{
$new = "false"; last;
}
}
close IP;
# ежели уникален, то...
if ($new eq "true")
{
WriteBase($IpFile, 3, "$ip $day+$mon"); # пишемся в базу
ReadBase($CountFile); # читаем статистику
$hits++;
$hosts++;
WriteBase($CountFile, 2, $hits, $hosts); # обновляем всю статистику
# если юзверь еще раз ломится на пагу, то...
else
{
ReadBase($CountFile); # читаем базу
$hits++; # обламываем его с хостами, но не с хитами
WriteBase($CountFile, 2, $hits, $hosts); # прежний хост и новый
ReadBase($CountFile); # хит
}
# выводим всю эту инфу в своеобразный каунтер
# мой с виду не отличить от натурального.
# рисуем картинку 88/31 и пишем её в Бекграунд
print "Content-type:text/html\n\n";
print qq\ # чтобы Принты сотню раз не печатать
<div style="pdding-left:3px;width:88px;height:31px;
background-image:URL(cgi-bin/counter.gif);
border-width:1px; border-style:solid; border-color:black;
font-family:Verdana;font-size:10px;color:white;text-align:right;line-height:13px">
$hits<br>
$hosts<br>
</div>\;
Как встроить счётчик
Для работы счётчика достаточно иметь любой сервер с поддержкой Perl и SSI. С
помощью второго мы можем вставить наш счётчик в любое место страницы вот так:
<!--#exec cgi="counter1.pl"-->
для скрипта права 755
для текстовых файлов 666
Ну... вот вроде бы и всё :)
Для новичков, возможно, сложно, но я сам полторы недели как новичок... был.
На самом деле главное понять принцип, вы и сами сможете написать что-то подобное
или даже лучшее, никто вас не ограничивает. Меня ограничил лишь световой день.
Perl советую всем! Он не лёгок, но две недели практики в писании скриптов вам
окупятся! Удачи!