Суббота, 21.12.2024
Меню сайта
Вход на сайт
Поиск
Статистика
Яндекс.Метрика
Реклама
HTML Perl PHP Прочее
Как написать счетчик посещаемости на Perl
В данной статье рассказано о том, как с помощью Perl и GD библотеки написать счетчик посещаемости.
Чем собственный счетчик лучше?
Существуют различные сервисы счетчиков, но всвязи с огромным количеством сайтов, на которых эти счетчики установлены, эти системы жудко тормозят. К примеру, HotLog падает как минимум раз в неделю, следовательно, посетители не учитываются. За эффективность так же берет деньги SpyLog.
Зачем платить деньги, если можно написать собственный счетчик с собственной статистикой?

Создание таблиц в MySQL.

Задумаемся, какую информацию о посетителе нам нужно знать.
По моим соображениям это должны быть:

  • время визита
  • IP посетителя
  • станица, с которой пришел посетитель
  • количество просмотренных страниц
  • страницы, которые посмотрел посетитель. Для экономии места лучше всего вносить первый и последний URL, который просмотрел посетитель.

    Соответственно создаем таблицу с вышеописанными столбцами:

    Code
    CREATE TABLE visitors (
    vtime datetime not null,
    ip text not null,
    referer text not null,
    hits int not null,
    firsturl text not null,
    lasturl text not null);

    Если задача счетчика - подсчиывать посетителей одного сайта, то можно ограничиться этой таблицей, если же нужно подсчитывать больше одного сайта, стоит завести еще одну таблицу со столбцами:

  • id сайта
  • посетителей всего было на сайте
  • посетители за сегодня
  • хиты за сегодня

    Скрипт счетчика.

    Code
    #/usr/bin/perl -w
    use DBI; # Загружаем модуль для работы с MySQL
    use GD; # Загружаем модуль для работы с графикой

    $w_database="counter"; # имя MySQL базы
    $w_host="localhost"; # Адерс MySQL сервера. Обычно MySQL сервер установлен вместе с web-server'ом, поэтому пишем localhost.
    $w_user=""; # Логин для входа в MySQL
    $w_password=""; # Пароль для входа в MySQL

    # Соединяемся с MySQL по заранее созданым: базе, пользователю, паролю
    $dbh = DBI->connect("DBI:mysql:$w_database:$w_host",$w_user,$w_password) || die $DBI::errstr;

    # Вычисляем сегодняшнюю дату и назначаем переменную, которая содержет дату в формате MySQL.
    ($Second, $Minute, $Hour, $DayOfMonth, $Month, $Year, $Weekday, $DayOfYear, $IsDST) = localtime(time);
    $RealYear = $Year + 1900; $Month++;
    if($Month < 10) {$Month = "0" . $Month}
    if($DayOfMonth < 10) {$DayOfMonth = "0" . $DayOfMonth}
    if($Hour < 10) {$Hour = "0" . $Hour}
    if($Minute < 10) {$Minute = "0" . $Minute}
    if($Second < 10) {$Second = "0" . $Second}
    $today = "$RealYear-$Month-$DayOfMonth $Hour:$Minute:$Seconds";

    # Разбор строки запроса
    if ($ENV{'REQUEST_METHOD'} eq "GET") { $query_string = $ENV{'QUERY_STRING'}; }
    elsif ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $query_string, $ENV{'CONTENT_LENGTH'}); }
    my @splitedqs = split (/&/, $query_string);
    foreach $splitedqs (@splitedqs) {
    @qskv = split (/=/, $splitedqs);
    $qskv[1] =~ tr/+/ /;
    $qskv[1] =~ s/%([dA-Fa-f][dA-Fa-f])/ pack ("C", hex ($1))/eg;
    $q{$qskv[0]} = $qskv[1];
    }

    Запись информации о посетителе в таблицу.
    Посетитель заходит на сайт, смотрим, первый ли раз он зашел на сайт за сегодня, одновременно проверяем количество хитов:

    Code
    $check= $dbh->prepare("SELECT hits FROM counter WHERE ip='$ENV{'REMOTE_ADDR'}' AND vtime='$today'") || die $DBI::errstr; # Берем количество хитов, если запись существует.
    $check->execute() or die $check->errstr;
    $ipcheck = $check->fetchrow; # Назначаем количество хитов указанной переменной.

    Теперь, если значение $ipcheck пустое, то посетитель зашел первый раз а этот день и его нужно добавить в таблицу.
    Если посетитель зашел не в первый раз, то значение $ipcheck содержит количество просмотренных страниц.

    $refererl=$ENV{'HTTP_REFERER'}; #Текущая страница
    $refererl =~ s/&/&/g; $refererl =~ s/</</g; $refererl =~ s/>/>/g; $refererl =~ s/
    //g; $refererl =~ s/
    //g; $refererl =~ s/,//g; $refererl =~ s/*//g; $refererl =~ s/#//g; $refererl =~ s/'//g; $refererl =~ s///g; # Проверка на лишние символы
    $hits=$ipcheck+1; # Плюс один хит (текущий)

    $wherefrom=$q{'r'}; # Реферал (URL)

    # ! сюда вставить проверку $wherefrom на лишние символы !

    if (!$ipcheck) { # старый посетитель
    $dbh->do("update counter set vtime='$today', hits='$hits', lasturl='$refererl'") or die $DBI::errstr or die $DBI::errstr;
    } else { # новый посетитель
    $dbh->do("insert into counter (vtime,ip,referer,hits,firsturl,lasturl) values ('$today','$ENV{'REMOTE_ADDR'}','$wherefrom','$hits','$refererl','$refererl')") or die $DBI::errstr or die $DBI::errstr;
    }

    Далее выводим общее количество посетителей и посетителей за сегодня.

    $check1= $dbh->prepare("SELECT hits FROM counter WHERE vtime='$today'") || die $DBI::errstr;
    $check1->execute() or die $check->errstr;
    $nn="0";
    while ($ipcheck1=$check1->fetchrow_hashref()) {
    $vhits=$vhits+$ipcheck1->{hits};
    $nn++;
    }

    $check2= $dbh->prepare("SELECT count(*) FROM counter") || die $DBI::errstr;
    $check2->execute() or die $check->errstr;
    $vall = $check2->fetchrow;

    Отображение счетчика.
    Счетчик можно взять как из картинки, так и нарисовать с нуля.
    Ниже приведен пример прорисовки счетчика по линиям.

    Code
    print "Content-type: image/png

    "; # Формат документа - картинка

    $im = new GD::Image(88,31); # Создаем изображение размером 88x31 пикселей

    # Назначаем цвета
    $white = $im->colorAllocate(255,255,255);
    $red = $im->colorAllocate(255,0,0);
    $blue = $im->colorAllocate(0,162,255);

    $im->rectangle(0,0,87,30,$red); # Рисуем рамку
    $im->fill(86,29,$blue); # Заливаем все синим
    $im->line(1,16,86,16,gbBrushed); Рисуем линии
    $im->line(67,16,60,29,gbBrushed);
    $im->line(37,1,31,16,gbBrushed);
    $im->fill(85,28,$white); # Два поля, отделенные линиями, заливаем белым
    $im->fill(1,1,$white);
    $im->rectangle(1,1,86,29,$white); # Белая рамка
    $im->rectangle(0,0,87,30,$blue); # Синяя рамка
    $im->string(gdSmallFont,3,2,"$vhits",$blue); # Выводим количество сегодняшних хитов
    $im->string(gdSmallFont,3,16,"$vall",$white); # Выводим количество всех посетителей
    $im->string(gdSmallFont,41,2,"WebZ.Ru",$white);
    $im->string(gdSmallFont,68,17,"$vtoday",$blue);# Выводим количество сегодняшних посетителей
    binmode STDOUT;
    print $im->png; # Вывод на экран

    Код счетчика.
    Код счетчика стостоит не только из картинки, но и из ява-скрипта, который должен передать страницу, с которой пришел новый посетитель.
    Чтобы счетчик не кэшировался, стоит в его код встроить случайное значение.Пример:

    Code
    <script language="JavaScript"><!--
    document.write("<a href=http://cc.webz.ru><img border=0 width=88 height=31 src=http://cc.webz.ru/?"+Math.random()+"&r="+document.referrer+"></a>");
    // --></script>
  • Perl 3454 24.05.2010
    Материалы по теме: