Отправляет email-рассылки с помощью сервиса Sendsay

Обучение и статьи по языку perl

  Все выпуски  

Обучение и статьи по языку perl


Служба Рассылок Subscribe.Ru проекта Citycat.Ru

Информационный клуб webмастеров Kwazar

Форум.

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

Данный форум состоит из следующих частей:

Начнем не с главной страницы,потому что она обобщает всю информацию,а с середины-добавления нового топика.

Добавление нового топика.

Сначала в директории cgi-bin веб-сервера создадим каталог html,куда будут записываться все сообщения. Сразу оговорюсь,что все сообщения пишутся в html-файл:сначала топик и сообщение,затем к нему дописываются ответы. По ходу дела все будет понятно.
Сгенерируем форму для добавления новой темы и сообщения.

#!/usr/local/bin/perl
#Webforum.cgi version 1.01
$request=$ENV{'REQUEST_METHOD'};
$content=$ENV{'CONTENT_LENGTH'};

$cgi="url/cgi-bin";
$url="url/cgi-bin/html";
$dir="/usr/local/apache/cgi-bin/html";

print "Content-type:text/html\n\n";
print <<HTML;
<html><head><style>a:link {text-decoration:none; }</style></head><body>
<h3 align=center><font color="0000ff">New topic</font></h3>
<p align=right><a href="$cgi/webforum.cgi"><font face="ferdana" size=3>
<b>Home</b></font></a>
<p><form action="$cgi/webforum.cgi" name="newtop" method="GET">
<table width=60% align=center bgcolor="e6e8fa">
<tr><td> 
<tr><td><b>Your nick:</b><td><input type="text" name="nick" size=20>
<tr><td><b>Topic name:</b><td><input type="text" name="theme" size=20>
<tr><td><input type="hidden" name="action" value="ok">
<tr><td colspan=2> <b>Message:</b><p>  
<textarea cols=40 rows=15 name="post" wrap="virtual"></textarea>
<tr><td colspan=2><input type="submit" value="Submit"></table>
HTML

Если данные введены в форму получаем их и декодируем.

@pairs = split(/&/, $query);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ s///g;
$name =~ s/<([^>]|\n)*>//g;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s///g;
$value =~ s/</</g;
$value =~ s/>/>/g;
$value =~ s/\cM/ /g;
$value =~ s/\|/ /g;
$value =~ tr/ / /s;
$value =~ s/<([^>]|\n)*>//g;
$value =~ s/"/"/g;
$value=~s/(http:\/\/\+S)/<A href="$1">$1<\/A>/g;
$input{$name} = $value;
}

$nick=$input {'nick'};
$theme=$input {'theme'};
$message=$input {'post'};

#Create new topic.

#Открываем каталог и читаем его содержимое.Файлы в каталог записываются в виде #001.html,002.html и т.д.То есть,каждый вновь записываемый файл,увеличивается #на единицу.Это делается следующим образом.

opendir (DIR,"$dir"); while (@mes=readdir (DIR)) { foreach $mes(@mes) { $count=@mes; $count++; $page="00".($count-2); }

# ($count-2)-это для того,чтобы не считать подкаталоги типа "." и "..". # Проверяем,не являются ли поля формы пустыми.Если нет-открываем файл на запись # и пишем информацию.

if ($nick ne "" && $theme ne "" && $message ne "") { open (FILE,">$dir/$page.html"); print FILE "<html><head><style>a:link {text-decoration:none; } </style><title>$theme</title>\n"; print FILE "<meta name=\"author\" content=\"$nick\"></head>\n"; print FILE "<body bgcolor=\"f6f8fa\">\n"; print FILE "<p align=right><a href=\"$cgi/webforum.cgi?action=reply&file=$page.html\">\n"; print FILE "<font face=\"ferdana\" size=3><b>Post reply</b></font></a>\n"; print FILE " <a href=\"$cgi/webforum.cgi\"><font face=\"ferdana\" size=3><b>Home</b></font></a><p>\n"; print FILE "<table width=90% cellpadding=0 cellspacing=0 border=1>\n"; print FILE "<tr><td align=center width=150 bgcolor=\"D5E6E1\"><font face=\"Arial\" size=2 color=\"808080\">Author</font>\n"; print FILE "<td bgcolor=\"D5E6E1\"><font face=\"serif\" size=2 color=\"0000ff\">Topic:</font>\n"; print FILE "<font face=\"serif\" size=2 color=\"ff0000\">$theme</font></td></tr>\n"; print FILE "<tr><td rowspan=2 bgcolor=\"D5E6E1\" align=center><font face=\"serif\" size=3 color=\"ff0000\">$nick</font></td>\n"; print FILE "<td bgcolor=\"e6e8fa\" height=30><font face=\"serif\" size=1 color=\"000080\">Posted:",scalar localtime,"</font></td></tr>\n"; print FILE "<tr><td bgcolor=\"f7f7f7\"><font face=\"serif\" size=2 color=\"000080\">$message</font></td></tr></table>\n"; close (FILE); } else {

#Если одно из полей формы осталось пустым-выдаем ошибку.Это делается для того,чтобы # не создавать пустые файлы,не содержащие информации.Perl'у все равно,что писать :)

print "Content-type:text/html\n\n"; print <<HTML; <p>  <p>  vp>  <body bgcolor="e6e8fa"> <h3 align=center>Sorry,you didn't enter your nick or message! </h3> <p><center><b>Please,go back and try again</b> <p><a href=\"$cgi/webforum.cgi?action=newtop\"><font face="ferdana" size=3> <b>Back</b></font></a> </center> HTML exit; } } closedir (DIR); }

# Если все прошло нормально,выносим пользователю благодарность.Новый топик создан.

print "Content-type:text/html\n\n"; print <<HTML; <p>  <p>  <p>  <body bgcolor="e6e8fa"> <h3 align=center>Thank you,<font color="0000ff">$nick!</font></h3> <p><center><b>Your message is added.</b> <p><a href="$cgi/webforum.cgi"><font face=\"ferdana\" size=3> <b>View topics</b></font></a></center> HTML </BODY> </HTML> HTML

Добавление ответа на топик.

Добавление ответа почти ничем не отличается от добавления топика,единственное отличие- нужно передать адрес страницы,чтобы скрипт знал,куда писать ответ.А он содержится в файле топика.Если посмотреть чуть выше,можно увидеть ссылку <a href="$cgi/webforum.cgi?action=reply&file=$page.html">Post reply</a> В ней и передается адрес страницы.
Генерируем форму:

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

$page=$input {'file'}; open (FILE,"$dir/$page"); @data=<FILE>; close (FILE); print "Content-type:text/html\n\n"; print <<HTML; <html><head><style>a:link {text-decoration:none; }</style></head><body> <h3 align=center><font color="0000ff">Post reply</font></h3> <p align=right><a href="$cgi/webforum.cgi"><font face="ferdana" size=3><b>Home</b></font></a> <p><form action="$cgi/webforum.cgi" name="reply" method="GET"> <table width=60% align=center bgcolor="e6e8fa"> <tr><td> <br><b>Your nick:</b><td>vinput type="text" name="nick" size=20> <tr><td><input type="hidden" name="type" value="reply"> <tr><td><input type="hidden" name="action" value="ok"> <tr><td><input type="hidden" name="file" value="$page"> <tr><td colspan=2> <b>Message:</b><p>   <textarea cols=40 rows=15 name="post"></textarea> <tr><td colspan=2><input type="submit" value="Submit"></table> <p><center><iframe src="$dir/$page" width=90% height=300></iframe></center> HTML #Reply to topic.

# Снова проверяем,чтобы поля формы не были пустыми.Если все в порядке,открываем файл, # содержащий топик на добавление и дописываем ответ.

if ($nick ne "" && $message ne "" ) { open (FILE,">>$dir/$page"); print FILE "<table width=90% cellpadding=0 cellspacing=0 border=1>\n"; print FILE "<tr><td rowspan=2 bgcolor=\"f7f7f7\" align=center width=150><font face=\"serif\" size=3 color=\"0000ff\">$nick</font></td>\n"; print FILE "<td bgcolor=\"e6e8fa\" height=30><font face=\"serif\" size=1 color=\"000080\">Posted:",scalar localtime,"</font></td></tr>\n"; print FILE "<tr><td bgcolor=\"f7f7f7\"><font face=\"serif\" size=2>$message</td></tr></table>\n"; close (FILE); close (FILE); } else {

# Если одно из полей осталось пустым-выдаем ошибку.

print "Content-type:text/html\n\n"; print <<HTML; <p>  <p>  <p>  <body bgcolor="e6e8fa"> <h3 align=center>Sorry,you didn't enter your nick or message! </h3> <p><center><b>Please,go back and try again</b> <p><a href=\"$cgi/webforum.cgi?action=reply&file=$page.html\"><font face="ferdana" size=3><b>Back</b></font></a> </center> HTML exit; }

# Снова выносим благодарность посетителю.Ответ добавлен.

print "Content-type:text/html\n\n"; print <<HTML; <p>  <p>  <p>  <body bgcolor="e6e8fa"> <h3 align=center>Thank you,<font color="0000ff">$nick!</font></h3> <p><center><b>Your message is added.</b> <p><a href="$cgi/webforum.cgi"><font face=\"ferdana\" size=3> <b>View topics</b></font></a></center> HTML </BODY> </HTML> HTML

Главная страница.

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

Данные на экран выводятся в виде html-таблицы.

print "Content-type:text/html\n\n";
print <<HTML;
<html><head><title>Webforum ver1.01</title>
<style>a: {text-decoration:none; } </style></head>
<body bgcolor="e6e8fa">
<p> 
<p><h2 align=center><font color="0000ff">Webforum</font></h2>
<p align=right><a href="$cgi/webforum.cgi?action=newtop">
<font face="ferdana" size=3><b>New topic</b></font></a>
<p><table width=700 cellpadding=0 cellspacing=0 border=1>
<tr bgcolor="D5E6E1"><td align=center width=300 height=50>
<font face="arial" size=2 color="0000ff">Topic name</font></td>
<td align=center width=150 height=50><font face="arial" size=2 color="0000ff">
Topic starter</font></td>
<td align=center width=50 height=50><font face="arial" size=2 color="0000ff">Replies</font></td>
<td align=center width=200 height=50><font face="arial" size=2 color="0000ff">Last post</font></td></tr>
HTML

# С этим,думаю,все понятно.А теперь более подробно о том,как получить всю эту информацию. # Открываем каталог и читаем сообщения в массив.

opendir (DIR,"$dir"); while (@mes=readdir(DIR)) { foreach $mes (@mes) {

# Каждый файл в каталоге открываем и читаем в массив.

if (!-d "$dir/$mes" && "$mes" ne "." && "$mes" ne "..") { $mtime=localtime((stat("$dir/$mes"))[9]); open (FILE,"$dir/$mes"); @lines=<FILE>; close (FILE);

# Теперь в каждом файле с помощью регулярных выражений ищем тему топика,имя автора топика # и количество ответов.

foreach $line (@lines) { if ($line=~ /<title>(.*?)<\/title>/is) { $title=$1; } if ($line=~ /content=\"(.*?)\"/is) { $name=$1; }

# Количество ответов помещаем в массив reply,отнимая единицу,так как первое сообщение-это # сообщение автора топика.

if ($line=~ /^<table(\s*)(.*?)>$/i) { $reply=$1; push (@reply,$reply); $char=@reply-1; } }

# Печатаем данные в таблицу,после каждой итерации очищая массив reply,чтобы ответы на # каждый топик не складывались после каждой итерации.

print <<HTML; <tr bgcolor="f7f7f7"><td height=30><a href="$url/$mes"> <font face="serif" size=2>$title</font></a></td> <td align=center height=30><font face="serif" size=2>$name</font></td> <td height=30 align=center>$char</td> <td height=30 align=center><font face="serif" size=2>$mtime</font></td></tr> HTML splice (@reply); } } } print "</table>\n"; closedir (DIR);

Ну вот,вроде бы и все.


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться Рейтингуется SpyLog

В избранное