Обьекты в модуле CGI.pm.
CGI-модуль можно рассматривать либо как традиционный модуль с экспортируемыми функциями, либо как обьектный модуль.
#!/usr/bin/perl5 -w
use 5.004; use strict; use CGI qw(:standard); use Fcntl qw(:flock);
sub bail { # функция ошибок my $error = "@_"; print h1("Unexpected Error"), p($error), end_html; die $error; }
my ( $CHATNAME, # имя файла гостевой книги $MAXSAVE, # какое количество хранить $TITLE, # название и заголовок страницы $cur, # все текущие записи $entry, # одна конкретная запись );
$TITLE = "Simple Guestbook"; $SHATNAME = "/usr/tmp/chatfile"; $MAXSAVE = 10;
print header, start_html($TITLE); h1($TITLE);
my(@entries);
$cur = CGI -> new(); # текущий запрос if($cur -> param("message")) { # мы получили сообщение $cur -> param("data", scalar localtime); # установить текущее время @entries = ($cur); # записать сообщение в массив }
# открыть файл для чтения и записи (с сохранением предыдущего содержимого) open(CHANDLE, "+< $CHATNAME") bail("canot open $CHATNAME: $!");
# получить эксклюзивную блокировку на гостевую книгу # (LOCK_EX == exclusive lock) flock(CHANDLE, LOCK_EX) bail("canot flock $CHATNAME: $!");
# занести в $MAXSAVE старые записи (первой - самую новую) while(!eof(CHANDLE) && @entries < $MAXSAVE) { $entry = CGI -> new(\*CHANDLE); # передать дескриптор файла по ссылке push @entries, $entry; } seek(CHANDLE, 0, 0) bail("canot rewind $CHATNAME: $!"); foreach $entry (@entries) { $entry -> save(\*CHANDLE); } truncate(CHANDLE, tell(CHANDLE)) bail("canot truncate $CHATNAME: $!"); close(CHANDLE) bail("canot close $CHATNAME: $!");
print hr, start_form; print p("Name:", $cur -> textfield(-NAME => "name")); print p("Message:", $cur -> textfield( -NAME => "message", -OVERRIDE => 1, # стирает предыдущее сообщение -SIZE => 50 ) ); print p(submit("send"), reset("clear")); print end_form, hr;
print h2("Prior Messages"); foreach $entry (@entiries) { printf("%s [%s]: %s", $entry -> param("date"), $entry -> param("name"), $entry -> param("message")); print br(); } print end_html;