|   | 
CGI-программирование.
Пример:
#!/usr/bin/perl5 -w
print <<END_of_Multiline_Text;
Content-type: text/html
<HTML>
	<HEAD>
	<Hello World!<TITLE>
	</HEAD>
	<BODY>
	<H1>Greetings, Terrians!<H1>
	</BODY>
</HTML>
End_of_Multiline_Text
 
Используется модуль CGI.pm. Программа, которая запрос: 
serv.edu.kiae.ru/~gds/cgi-bin/test.cgi?flavor=mint:
#!/usr/bin/perl5 -w
use CGI qw(param);
print <<END_of_Multiline_Text;
Content-type: text/html
<HTML>
	<HEAD>
	<Hello World!<TITLE>
	</HEAD>
	<BODY>
	<H1>Greetings, Terrians!<H1>
End_of_Multiline_Text
my $favorilte = param("flover");
print "<P>Your favorite flavor is $favorite.";
print <<All_Done;
	</BODY>
	</HTML>
All_Done
В модуле CGI.pm имеются директивы импорта - метки, которые обозначают
группы импортируемых функций. В модуле имеются следущие директивы:
:cgi, :form, :html2, :html3, :netscape, :shortcuts, :standard, :all.
Пример использования сокращений:
 
#!/usr/bin/perl5 -w
use CGI qw(:standard);
print header();
print start_html("Hello World!"), h1("Hello World!");
my $favorite = param("flavor");
print p("Your favorite flavor is $favorite");
print end_html();
HTML-страница, содержащая заполняемую форму:
<HTLM>
	<HEAD>
	<TITLE> Hello Ice Cream </TITLE>
	</HEAD>
	<BODY>
	<H1>Hello Ice Cream!</H1>
	<FORM ACTION="http://serv.edu.kiae.ru/~stsss/cgi-bin/ice_cream.cgi" METHOD="GET">
	What is your flavor?<INPUT NAME="favorite" TYPE="text" VALUE="mint">
	<P>
	<INPUT TYPE="submit">
	</FORM>
	</BODY>
</HTLM>
 
Вариант с использованием одного CGI-файла:
#!/usr/bin/perl5 -w
use CGI qw(:standard);
my $favorite = param("flavor");
print header();
print start_html("Hello Ice Cream!"), h1("Hello Ice Cream!");
if($favorite) {
	print p("Your favorite flavor is $favorite");
} else {
	print hr, start_form;
	print p("Pleace select a flavor: ", textfield("flavor", "mint"));
	print end_form, hr
}
print end_html();
Пример:
#/usr/bin/perl5 -w
use strict;
use CGI qw(:standard);
print header;
print start_html("Ice Cream Stand"), h1("Ice Cream Stand");
if(param()) {
	my $who = param("name");
	my $flavor = param("flavor");
	my $scoops = param("scoops");
	my $taxrate = 1.0743;
	my $cost = sprintf("%.2f", $taxrate * (1.00 + $scoops*0.25));
	print p("Ok, $who, have $scoops scoops of $flavor for\$$cost.");
} else {
	print hr();
	print start_form();
	print p("What is your name? ", textfield("name"));
	print p("What flavor: ", popup_menu("flavor",
						['mint', 'cherry', 'mocha']));
	print p("How many scoops? ", popup_menu("scoops", [1..3]));
	print p(submit("order"), reset("clear"));
	print end_form(), hr();
}
print end_html();
В функции popup_menu() квадратные скобки создают ссылку
на анонимный массив. Другой способ создания ссылки на массив:
@choises = ('mint', 'cherry', 'mocha');
print p("What flavor: ", popup_menu("flavor",\@choises));
Ссылки работают примерно как ссылки в C. Они указывают на другие
значения или переменные. Сылки PERL нельзя приводить. Если область
памяти, на которую указывают ссылки, больше не используется, автоматически
возвращается в использование.
Методом \@array можно создавать ссылки на именованные
массивы, а посредством указания [ list ] - на анонимные
массивы.
 
Методом \%hesh можно создавать ссылки на именованные
хеши, а посредством указания { key1, val1, key2, val2, .. } 
- на анонимные хеши.
 
Прокручиваемый список:
print scrolling_list(
	-NAME => "flavors",
	-VALUES => [qw(mint chocolate cherry vanilla peach)],
	-LABELS => {
		mint => "Mightly Mint",
		chocolate => "Cherished Chocolate",
		cherry => "Cherry Cherry",
		vanilla => "Very Vanilla",
		peach => "Perfectly Peach",
	},
	-SIZE => 3,
	-MULTIPLE => 1	# 1 - true, 0 - false
);
-NAME - имя компонента формы,
 -LABELS - ссылка на анонимный хеш,
 -VALUES - ссылка на анонимный массивa ключей хеша,
 -SIZE - сколько элементов списка видно одновременно,
 -MULTIPLE - если 1 - можно выбирать более одного
элемента списка.
 Если -MULTIPLE в положении истина, можно делать:
 
@choices = param("flavors");
Еще один способ:
 
%flavors = (
		"mint", "Mightly Mint",
		"chocolate", "Cherished Chocolate",
		"cherry", "Cherry Cherry",
		"vanilla", "Very Vanilla",
		"peach", "Perfectly Peach",
	);
print scrolling_list(
	-NAME => "flavors",
	-LABELS => \%flavors,
	-VALUES => [keys %flavors],
	-SIZE => 3,
	-MULTIPLE => 1	# 1 - true, 0 - false
);
 
Создание файла:
touch /usr/tmp/chatfile
chmod 0666 /usr/tmp/chatfile
 
Блокирование доступа:
use Fcntl qw(:flock);	# импортирует LOCK_EX, ...
...
flock(CHANDLE, LOCK_EX) || bail("Cannot flock $CHATNAME: !$");
Пусть модуль CGI возвращает обьект $query
$he_said = $query->param("answer");
Имя класса - имя модуля без расширения .pm (обычно).
Конструктор, необходимый для создания обьекта:
 
$query = CGI->new();
# or
$query = new() CGI;
 
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;
								
 | 
  |