Практические примеры программирования cgi-скриптов на Perl: форум.
Форум.
Форумы в Интернете можно встретить сплошь и рядом.Ни один уважающий себя сайт не обходится без них.
Форум дает возможность узнать мнение посетителей о сайте и о том,что они думают об авторе и о
его творениях :).
Форум,пример которого я здесь приведу не очень сложный,но он обеспечивает все необходимые функции.Для лучшего понимания имеет
смысл разбить его на несколько частей,объяснить каждую в отдельности,а затем объединить все вместе.
Данный форум состоит из следующих частей:
- Главная страница-вывод списка топиков ( http://webscript.ru/#ex1 ).
- Создание нового топика и запись в файл. ( http://webscript.ru/#ex2 )
- Создание ответа на топик и запись в файл. ( http://webscript.ru/#ex3 )
Начнем не с главной страницы,потому что она обобщает всю информацию,а с середины-добавления нового топика.
Сначала в директории 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/htmlnn";
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/(//+S)/<A href="$1">$1</A>/g;
$input{$name} = $value;
}
$nick=$input {'nick'};
$theme=$input {'theme'};
$message=$input {'post'};
#Create new topic.
opendir (DIR,"$dir");
while (@mes=readdir (DIR)) {
foreach $mes(@mes) {
$count=@mes;
$count++;
$page="00".($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 {
print "Content-type:text/htmlnn";
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/htmlnn";
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/htmlnn";
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/htmlnn";
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/htmlnn";
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/htmlnn";
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;
}
if ($line=~ /^<table(s*)(.*?)>$/i) {
$reply=$1;
push (@reply,$reply);
$char=@reply-1;
}
}
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://webscript.ru///webscript.virtualave.net/prog/perl/listforum.html ),а пример работы-
здесь ( http://webscript.ru///webscript.virtualave.net/cgi-bin/webforum.cgi ),на страницах этого сайта.
Конечно,я не реализовал все возможности.Можно добавить регистрацию пользователя,возможность редактирования
сообщений и т.д.В дальнейшем я планирую доработать этот форум и сделать его более продвинутым.
В данный момент моей целью было объяснить,как это работает.Если я достиг ее-буду рад.
Если вам понравился этот материал-оставьте свой комментарий.
Кстати,более крутой форум написанный на PHP с использованием базы данных MySQL,вы можете
посмотреть и скачать в Каталоге скриптов ( http://webscript.ru///webscript.virtualave.net/cgi-bin/dirviewer.cgi ).В нем я реализовал
все возможности,не реализованные здесь.Скоро я опишу процесс создания такого форума.
|