Создание счетчика посещений на 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 советую всем! Он не лёгок, но две недели практики в писании скриптов вам
окупятся! Удачи!