Гостевая книга.

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

В данном примере мы будем записывать полученные данные в конец файла, содержащего форму (gb.html).На рисунке слева - внешний вид гостевой книги.

<HTML>
<HEAD>
<TITLE>Гостевая книга</title>
<META content="text/html; charset=windows-1251" http-equiv=Content-Type>
</head>
<BODY bgcolor=#000000 text="Lightslategray">
Здесь объяснять ничего не нужно. Текст приведен лишь для сохранения целостности.


<FORM METHOD = POST ACTION = "gb.cgi">
Будем использовать метод Post. Про методы запроса (post и get) можно почитать здесь. Введенные данные передаются скрипту gb.cgi.

<H3>Добавить комментарии:</h3>
<TABLE>
<TR>
<TH>Имя:</th>
<TH><INPUT type ="text" name="name"></input></th>
</tr>

Создаем строку для ввода текста.
<TR>
<TH>Комментарии:</th>
<TH><textarea cols=50 rows=3 name="comments"></textarea></th>
</tr>

Создаем многострочное текстовое поле.


</table>
<INPUT type ="submit" value="Отправить">
<INPUT type ="reset" value="Сброс">
Кнопки подтверждения и отмены.

<HR size=4 color=black>
<TABLE border=1, bdcolor=grey, width=100%>

----------> именнно сюда будут добавляться новые записи
 </table></body></html>

Теперь перейдем к скрипту ( файл gb.cgi).

#!c:\perl\bin\perl.exe
use CGI;
$cgi_obj=new CGI;
open (f,
"+<gb.html") or die("");
seek(f, -22,2);

С файлами мы уже работали в предыдущем примере, поэтому ограничимся кратким пояснением. Отступим с конца файла на 22 байта (именно столько занимает строчка "</table></body></html>"). Можно  использовать функцию length  для определения величины отступа (к примеру, seek(f, -length($co->end_html);).

print $cgi_obj->start_html(
-title=>
'Гостевая книга',
-bgcolor=>
'black',
-text=>
'Lightslategray');


$name=$cgi_obj->param(
'name');
$text=$cgi_obj->param(
'comments');
Чтобы обрабатывать введенные  данные, присвоим скалярным переменным  содержимое соответствующих текстовых полей.

if (length($name)!=0 && length($text)!=0){

Проверим, не оставил ли пользователь поля пустыми.

$text=~ s/</&lt/;
$name=~ s/</&lt/;
Не позволим браузеру исполнять  код HTML, введенный в  в многострочное текстовое поле или поле для имени! Будем заменять символ "<" на "&lt"!

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

print f "<TR><TH align=center>",$name, "</TH><TH align=left>";
Гостевая книга будет иметь вид таблицы.

@a=split /[,\s]\s*/, $text;
В результате получаем массив, элементами которого являются слова, содержащиеся в текстовом поле "comments" (используем функцию split и регулярные выражения для разбиения строки на слова).

$j=0;
$len=0;
while (@a[$j]){
if ($len+length(@a[$j])>100){
print f "<BR>";
$len=0;
};
print f @a[$j], " ";
$len+=length(@a[$j]);
$j++;
};
С помощью этого цикла организован перенос по словам. Если при добавлении очередного слова длина получившейся строки  превысит допустимую (в данном случае, 100), то слово будет выведено лишь в следующей строке.

print f "</TH></TR>";
print
"Запись добавлена.",$cgi_obj->a(
{href=>
"gb.html"},"Назад"), $cgi_obj->end_html;
}

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

else {
print"Ощибка ввода. Нажмите ",$cgi_obj->a(
{href=>
"gb.html"},"сюда"),", чтобы исправиться", $cgi_obj->end_html;
}

Если же пользователь ввел некорректные данные или оставил поля пустыми, то дадим ему шанс исправиться.


print f "</table></body></html>";
close f

И, конечно, не забудем закрыть файл.
Посмотреть, как это работает можно на нашем сайте в разделе "Общение".

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