Практические примеры программирования cgi-скриптов на Perl: счетчики посещений.


Прислал: OlegTr [ 12.03.2001 @ 05:28 ]
Раздел:: [ Статьи по Perl ]


Счетчики посещений.

Пример 1.

Рассмотрим простейший текстовый счетчик,который подсчитывает общее количество посещений и выводит результат на экран.
Определяем путь к файлу,в котором будут храниться показания счетчика:

#!/usr/local/bin/perl
#textcounter
$file="counter1.txt";

Открываем файл на чтение,инициализируем счетчик и увеличиваем его значение на единицу:

open (STAT,"$file");
$count=;
close (STAT);

$count++;

Открываем файл счетчика на запись и записываем новое значение:

open (STAT,">$file");
print STAT $count;
close (STAT);

И,наконец,выводим показания счетчика на экран:

print "Content-type:text/html\n\n";
print $count;

Если сохранить данный код в файле counter1.cgi и открыть его в браузере,то на экране мы увидим 1.Если перезагрузить страницу,показание счетчика увеличится на 1. Выводить результаты счетчика можно как кому подскажет фантазия-или просто в виде числа,или вставить его в таблицу,ипользовав в качестве бэкграунда какой-нибудь фон и т.д. Вставить счетчик в html-страницу можно,используя SSI.Для этого в том месте,где предполагается использовать счетчик,вставьте следующий код:

<!--#exec cgi="path/to/counter1.cgi" -->

Листинг примера 1.
#!/usr/local/bin/perl
#textcounter
$file="counter1.txt";
open (STAT,"$file");
$count=;
close (STAT);

$count++;

open (STAT,">$file");
print STAT $count;
close (STAT);

print "Content-type:text/html\n\n";
print $count;

Посмотреть работу ( http://webscript.ru///webscript.virtualave.net/prog/perl/demo1.html )

Пример 2.

Усложним предыдущий пример,например,добавив запись в лог-файл,для сбора статистики и сделаем так,чтобы счетчик выводил результат в виде 6 цифр с заполнением впереди нулями,к примеру так:000143 Предыдущая часть кода останется без изменений,только добавим переменную для количества цифр результата.

#!/usr/local/bin/perl
#textcounter
$file="counter2.txt";
$dig_num=6;

open (STAT,"$file");
$count=;
close (STAT);

$count++;

open (STAT,">$file");
print STAT $count;
close (STAT);

Далее добавляем следующее:

open (DATA,">>counter.log");
$string=join ('&',$ENV {'REMOTE_ADDR'},$ENV {'REMOTE_HOST'},scalar localtime);
print DATA "$string\n";
close (DATA);

В этом случае скрипт создаст файл counter.log и всякий раз при перезагрузке страницы будет записывать данные о пользователе-его IP-адрес,имя хоста и время посещения.
Думаю,с этим все понятно.Теперь определим,как скрипт будет выводить результат:

@digits=split (//,$count);   #Читаем строку файла счетчика в массив и разбиваем на цифры.
$number=@digits;             #Подсчитываем количество цифр.

if ($number < $dig_num) {
$diff=$dig_num-$number;      #Сравниваем количество цифр в строке с заданным.
$count="0"x$diff.$count;
} else {
$count=$count;
}

print "Content-type:text/html\n\n"; #Выводим результат
print "$count\n";

Листинг примера 2.
#!/usr/local/bin/perl
#textcounter
$file="counter2.txt";
$num_dig=6;

open (STAT,"$file");
$count=;
close (STAT);

$count++;

open (STAT,">$file");
print STAT $count;
close (STAT);

open (DATA,">>counter.log");
$string=join ('&',$ENV {'REMOTE_ADDR'},$ENV {'REMOTE_HOST'},scalar localtime);
print DATA "$string\n";
close (DATA);

@digits=split (//,$count);
$number=@digits;

if ($number < $dig_num) {
$diff=$dig_num-$number;
$count="0"x$diff.$count;
} else {
$count=$count;
}

print "Content-type:text/html\n\n";
print $count;

Посмотреть работу ( http://webscript.ru///webscript.virtualave.net/prog/perl/demo2.html )  Скачать ( http://webscript.ru///webscript.virtualave.net/upload/counter2.zip )

Пример 3.

Далее приведу пример более сложного счетчика,который не только пишет в лог,но и подсчитывает количество посещений общее и за сегодняшний день.Также имеется возможность просмотра статистики через Интернет.Это может делать только хозяин счетчика,вводя свой пароль.
Начальная часть скрипта без изменений.

#!/usr/local/bin/perl
#textcounter

$file="counter.txt";

open (STAT,"$file");
$count=;
close (STAT);

$count++;

open (STAT,">$file");
print STAT $count;
close (STAT);

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

($sec,$min,$hour,$day,$month,$year,$day2)=localtime(time);
if ($hour<10) {
$hour="0".$hour;
} else {
$hour=$hour;
}

if ($min<10) {
$min="0".$min;
} else {
$min=$min;
}

if ($hour<12) {
$time=$hour.":".$min." AM";
} else {
$time=($hour-12).":".$min." PM";
}

if ($month<10) {
$month="0".($month+1);
} else {
$month=$month+1;
}
$date=$day."/".$month."/".($year+1900);

В таком виде оно и будет записываться в лог.

open (LOG,">>counter.log");
$string=join('&',$date,$time,$ENV {'REMOTE_ADDR'},$ENV {'REMOTE_HOST'});
print LOG $string,"\n";
close (LOG);

Следующий шаг-читаем файл посещений за сегодня,затем открываем для чтения лог и сравниваем дату для каждой строки с сегодняшней.Если они совпадают-увеличиваем показания счетчика и записываем новые показания в файл.

open (NOW,"today.txt");
$today=;
close (NOW);

open (LOG,"counter.log");
@data=;
close (LOG);

foreach $string(@data) {
@item=split(/&/,$string);

if ($item[0]=~/$date/i) {
push (@now,$item[0]);
$size=@now;
$today=$size;

} else {
$today=0;
}
}
open (NOW,">today.txt");
print NOW $today;
close (NOW);

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


print "Content-type:text/html\n\n";
print "<html><head><style>a {text-decoration:none;}
a:visited {text-decoration:none;}
a:hover {text-decoration:none;}</style></head><body link=\"ffffff\" alink=\"ffffff\" vlink=\"ffffff\">\n";
print "<table width=100 height=40 cellspacing=0 cellpadding=0 border=1>\n";
print "<tr><td rowspan=2 width=30 bgcolor=\"3399ff\" bordercolor=\"0000ff\">
<font face=\"serif\" size=2 color=\"ffffff\">
<a href=\"javascript:window.open ('../cgi-bin/stat.cgi','Statistics','width=600,
height=400,scrollbars=1')\">
<b>MY<br>STAT</b></a></font></td>\n";
print "<td align=right bgcolor=\"000000\" bordercolor=\"000000\" height=10>
<font size=1 color=\"ffffff\">",$time,"</font></td></tr>\n";
print "<tr><td align=right valign=bottom bgcolor=\"f6f8fa\">
<font face=\"serif\" size=1 color=\"ff0000\"><b>",$today,"<br>
",$count,"</b></font></td></tr>\n";
print "</table>\n";

Как вы заметили в последнем фрагменте имеется ссылка на другой скрипт-для просмотра статистики посещений. Его тоже нужно создать.Этот скипт получает данные из формы(в данном случае это пароль), декодирует их.Если пароль введен правильно,скрипт открывает лог счетчика,читает данные из него и выводит на страницу,начиная с самых последних.

#!/usr/local/bin/perl

$password="password";

$request=$ENV{'REQUEST_METHOD'};
$content=$ENV{'CONTENT_LENGTH'};


###################################################################29

#Функция для декодирования данных.

sub urldecode {
local($val)=@_;
$val=~ s/\+/ /g;
$val=~ s/%[0-9a-hA-H] {2}/pack('C',hex($1))/ge;
return $val;
}

#####################################################################

if ($request eq 'GET') {
$query=$ENV{'QUERY_STRING'};
}
else {
sysread(STDIN,$query,$content);
}

if ($query eq '') {

#Генерируем форму

print "Content-type:text/html\n\n";
print <;
print "Content-type:text/html\n\n";
print <=$[;$i--) {
@item=split ('&',$lines[$i]);
print "<tr><td align=center>",$item[0],"</td><td align=center>",
$item[1],"</td><td align=center>",$item[2],"</td><td align=center>",
$item[3],"</td></tr>\n";
}
print "</table>\n";
close (STAT);
}

#Если пользователь ввел неверный пароль.
else {
print "Content-type:text/html\n\n";
print "<body bgcolor=\"f6f8fa\">\n";
print "<h2 align=center><font color=\"ff0000\">Error!Password incorrect.
</font></h2>\n";
print "<p><center>Access denied!</center>\n";
}
}

Посмотреть работу ( http://webscript.ru///webscript.virtualave.net/prog/perl/demo3.html )  Скачать ( http://webscript.ru///webscript.virtualave.net/upload/counter.zip )

Пример 4.

Рассмотрим пример графического счетчика,который выводит результат на экран в виде графических цифр.Для этого немного преобразуем пример 2.

#!/usr/local/bin/perl
#graphcounter

$file="counter.txt";
$dig_num=6;

#Указываем путь к картинкам.
$path="path/to//images";
$dig1="1.gif";
$dig2="2.gif";
$dig3="3.gif";
$dig4="4.gif";
$dig5="5.gif";
$dig6="6.gif";
$dig7="7.gif";
$dig8="8.gif";
$dig9="9.gif";
$dig0="0.gif";

#Записываем показания счетчика в файл.
open (STAT,"$file");
$count=;
close (STAT);

$count++;

open (STAT,">$file");
@digits=split (//,$count);
$number=@digits;

if ($number < $dig_num) {
$diff=$dig_num-$number;
$count="0"x$diff.$count;
} else {
$count=$count;
}
print STAT $count;
close (STAT);

Показания записываются в файл в виде 000345,т.е. 6 цифр.Теперь необходимо разбить строку файла на символы и каждый символ сопоставить с графическим файлом.Это делается следующим образом:

open (STAT,"$file");
$line=;              #Читаем содержимое файла в строку.
@numbers=split (//,$line); #Разбиваем строку на символы.
close (STAT);

#Сопоставляем цифры с образцом и выводим результат на экран.
print "Content-type:image/gif\n\n";
foreach $dig (@numbers) {
$dig =~ s/1/<img src=$path\/$dig1>/g;
$dig =~ s/2/<img src=$path\/$dig2>/g;
$dig =~ s/3/<img src=$path\/$dig3>/g;
$dig =~ s/4/<img src=$path\/$dig4>/g;
$dig =~ s/5/<img src=$path\/$dig5>/g;
$dig =~ s/6/<img src=$path\/$dig6>/g;
$dig =~ s/7/<img src=$path\/$dig7>/g;
$dig =~ s/8/<img src=$path\/$dig8>/g;
$dig =~ s/9/<img src=$path\/$dig9>/g;
$dig =~ s/0/<img src=$path\/$dig0>/g;
print $dig;
}

#Записываем данные в лог.
open (DATA,">>counter.log");
$string=join ('&',$ENV {'REMOTE_ADDR'},$ENV {'REMOTE_HOST'},scalar localtime);
print DATA "$string\n";
close (DATA);
#Все.

Листинг примера 4.
#!/usr/local/bin/perl
#graphcounter

$file="counter.txt";
$dig_num=6;

#Указываем путь к картинкам.
$path="path/to//images";
$dig1="1.gif";
$dig2="2.gif";
$dig3="3.gif";
$dig4="4.gif";
$dig5="5.gif";
$dig6="6.gif";
$dig7="7.gif";
$dig8="8.gif";
$dig9="9.gif";
$dig0="0.gif";

#Записываем показания счетчика в файл.
open (STAT,"$file");
$count=;
close (STAT);

$count++;

open (STAT,">$file");
@digits=split (//,$count);
$number=@digits;

if ($number < $dig_num) {
$diff=$dig_num-$number;
$count="0"x$diff.$count;
} else {
$count=$count;
}
print STAT $count;
close (STAT);

open (STAT,"$file");
$line=;              #Читаем содержимое файла в строку.
@numbers=split (//,$line); #Разбиваем строку на символы.
close (STAT);

print "Content-type:image/gif\n\n";
foreach $dig (@numbers) {
$dig =~ s/1/<img src=$path\/$dig1>/g;
$dig =~ s/2/<img src=$path\/$dig2>/g;
$dig =~ s/3/<img src=$path\/$dig3>/g;
$dig =~ s/4/<img src=$path\/$dig4>/g;
$dig =~ s/5/<img src=$path\/$dig5>/g;
$dig =~ s/6/<img src=$path\/$dig6>/g;
$dig =~ s/7/<img src=$path\/$dig7>/g;
$dig =~ s/8/<img src=$path\/$dig8>/g;
$dig =~ s/9/<img src=$path\/$dig9>/g;
$dig =~ s/0/<img src=$path\/$dig0>/g;
print $dig;
}

open (DATA,">>counter.log");
$string=join ('&',$ENV {'REMOTE_ADDR'},$ENV {'REMOTE_HOST'},scalar localtime);
print DATA "$string\n";
close (DATA);

Посмотреть работу ( http://webscript.ru///webscript.virtualave.net/prog/perl/demo4.html )  Скачать ( http://webscript.ru///webscript.virtualave.net/upload/graphcount.zip )

Примеров можно привести множество.Наверное,каждый веб-программер пишет счетчики по-своему. Но я думаю,что приведенные примеры помогут вам понять основной принцип написания счетчиков посещений и создать свой собственный,подобных которому нет :)))

Удачи.