Реферат: Практический Перл для начинающего

Данная работа написана для людей, которым в силу непреодолимых обстоятельств приспичило срочно изучить Перл. Для меня таким обстоятельством стало то, что мой компьютер стал WEB-сервером, а я, соответственно, WEB-мастером. Учиться принято на чужих ошибках и опыте, поэтому предлагаю Вашему вниманию свой опыт изучения Перла.

Сразу нужно пояснить, для кого это все написано. Если Ваш сервер работает на платформе UNIX, то это я должен читать Вашу статью. Уменяжеустановлен Windows NT workstation 4.0 (RUS) плюс Service Pack 3. Когда пришло время сделать из компьютера WEB-сервер, я было кинулся ко встроенным Службам узла WEB, но быстро понял, что это мне не нравится (почему ?). И тут один добрый человек посоветовал поставить Xitami WEB Server от iMatix Corporation (http://www.imatix.com/), который и стоит по сей день.

Что касается самого Перла, то здесь несколько сложнее. Покопавшись по различным Перловым серверам (www.perl.org, www.perl.com ) я узнал, что версий Перла настолько много, что выбрать что-нибудь конкретное довольно сложно. При этом каких-нибудь вразумительных рекомендаций по поводу выбора той или иной версии нигде нет. Перепробовав почти все версии для Windows, я остановил свой выбор на Active Perl (http://www.activestate.com/).

Человеку, избалованному всякими Виндовозами и Дельфями, писать программы на Перл довольно непривычно, поэтому настоятельно рекомендую сразу установить Perl Builder. Взять его можно на www.solutionsoft.com. Там лежала тридцатидневная Демо версия.

Ну, думаю, пора переходить непосредственно к делу. В общем случае, скрипт на Перл, как и любая другая программа, работает так:

получает данные

обрабатывает данные

выдает результаты

Передать данные скрипту можно двумя методами — GET и POST. Разница между ними в том, что при использовании GET данные постоянно болтаются в строке адреса браузера, напимер:

httр://treagraf.tasur.edu.ru/cgi-bin/price.pl?Category=POWER&Description=varta

В этом случае скрипт B_price.pl берет данные в переменной окружения QUERY-STRING.

$data=$ENV{'QUERY_STRING'};

При использовании метода POST данные передаются на стандартный вход скрипта. Длинна блока данных берется в переменной CONTENT_LENGTH:

read(STDIN,$data,$ENV{'CONTENT_LENGTH'});

Теперь эти данные нужно перевести в удобоваримый вид, поскольку они закодированы.

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

treagraf.tasur.edu.ru/cgi-bin/B_price.pl?Category=%C2%E8%E4%E5%EE&Description=%E0%E1%E2%E3

Это значит:

treagraf.tasur.edu.ru/cgi-bin/B_price.pl?Category=Видео&Description=абвг

Декодировать строку запросов в первый раз лучше самому. На вопрос «а как?» есть множество ответов, переписывать которые нет смысла. Приведу лишь короткий пример:

Заменяем знаки (+) на пробелы

$query = ~ s/\+/ /g;

Потом заменяем все сочетания знака (%), после которого следуют шестнадцатиричные цифры, на соответствующий символ ASCII

$query =~ s/%([0-9A-H]{2})/pack('C', hex($1))/eg;

Я пользуюсь тем, что предлагает Perl Builder:

#! E:\perl5\bin\perl

&GetFormInput; # вызов подпрограммы получения данных

$Category = $field{'Category'}; # получаем данные из поля Category

$Description = $field{'Description'}; # получаем данные из поля Description

$Page = $field{'Page'}; # получаем данные из поля Page

В конце скрипта помещаем подпрограмму «прозрачного» чтения данных.

sub GetFormInput {

(*fval) = @_ if @_;

local ($buf);

if ($ENV{'REQUEST_METHOD'} eq 'POST') {

read(STDIN,$buf,$ENV{'CONTENT_LENGTH'});

}

else {

$buf=$ENV{'QUERY_STRING'};

}

if ($buf eq "") {

return 0;

}

else {

@fval=split(/&/,$buf);

foreach $i (0… $#fval){

($name,$val)=split (/=/,$fval[$i],2);

$val=~tr/+/ /;

$val=~ s/%(..)/pack(«c»,hex($1))/ge;

$name=~tr/+/ /;

$name=~ s/%(..)/pack(«c»,hex($1))/ge;

if (!defined($field{$name})) {

$field{$name}=$val;

}

else {

$field{$name} .= ",$val";

#if you want multi-selects to goto into an array change to:

#$field{$name} .= "\0$val";

}

}

}

return 1;

}

Второй этап работы скрипта — обработка данных — полностью на Ваше усмотрение. Проверяйте полученные данные на правильность, пишите их в файл, делайте что хотите.

И, наконец, Вам нужно выдать какие-то результаты броузеру клиента, причем так, чтобы броузер правильно их отобразил. То есть, выдавать результаты нужно в HTML. Это делается просто: (тоже можно по-разному)

print 'Content-type: text/html', "/n/n"; #обязательнаястрока

print '

Вполе Category Выввели: ', $Category, '

',"\n"

Все это касается скриптов, получающих данные из формы на странице HTML. При этом страница с формой — отдельно, скрипт — отдельно. Можно сделать красивее и удобнее: объединить страницу и скрипт в единое целое. Для этого скрипт пишется по схеме:

При первом запуске скрипт рисует HTML страницу с формой и ссылкой в тэге ACTION на самого себя. Первый запуск определяется по отсутствию входных данных.

Если входные данные есть, то получаем их, обрабатываем и выдаем результаты.

Пример:

#! E:\perl5\bin\perl

if (($ENV{'QUERY_STRING'} eq '') or ($ENV{CONTENT_LENGTH}=0) )

{ # генерируем страницу с формой }

else

{# получаем данные, обрабатываем и выдаем результат}

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

Общий алгоритм работы гостевой книги таков:

1. Если посетитель хочет сделать запись в книгу, то

1.1 Получаем данные

1.2 Записываем их в файл или в базу данных

1.3 Говорим спасибо на HTML и предлагаем почитать другие записи

2. Если посетитель хочет почитать записи в книге, то

2.1 Читаем записи из файла или из базы данных

2.2 Выводим их красиво в HTML

Для удобства восприятия я оформил пункты 1 и 2 отдельными скриптами add_guestbook.pl и read_guestbook.pl соответственно. Сообщения гостевой книги хранятся в текстовом файле построчно, т.е. на каждую запись — строка. Так сделано для удобства чтения этого файла. Пример одной записи:

Sat Dec 5 13:31:20 1998&Наташа&студентка&Good&Для начала хорошо. Успехов на данном поприще Вам, Александр!&нету@пока&194.226.60.34

Вот описание полей рассматриваемой гостевой книги.

Name — имя, фамилия, отчество, кличка — на усмотрение посетителя

Work — профессия, род занятий

RadioButton — три кнопки: понравилось (Good), не понравилось (Bad), пофигу (Different)

Text — text box комментариев и примечаний

Email — обратный адрес

add_guestbook.pl — запись в книгу

#! e:\perl5\perl

# Первая строка, как обычно

require «ssi-pl.pl»;

# Я использую навигационную панель в виде SSI-включения. Для этого используется модуль ssi-pl.pl

if (($ENV{'QUERY_STRING'} eq '') or ($ENV{CONTENT_LENGTH}=0) )

{

# Если нет входных данных, то генерируем страницу с формой

print <

<head>

<meta http-equiv=«Content-Type» content=«text/html; charset=windows-1251»>

<meta name=«GENERATOR» content=«Microsoft FrontPage 3.0»>

<title>Книга жалоб и предложений</title>

</head>

<body background="../images/background_new.jpg">

<div align=«left»>

<table border=«0» width=«630» height=«49»>

<tr>

<td width=«200» height=«45»></td>

<td width=«430» height=«45»><p align=«center»><img src="../images/guestbook.GIF"

alt=«Книгажалоб» WIDTH=«258» HEIGHT=«60»></td>

</tr>

</table>

</div><div align=«left»>

<table border=«0» width=«630» height=«53» cellspacing=«0» cellpadding=«0»>

<tr>

<td width=«200» height=«260» valign=«top»>

<p align=«center»>

HTML

DoInclude("_menu.htm"); # Это SSI-включение навигационной панели.

print <<HTML;

</p>

<p align=«left»></td>

<td width=«10» height=«53» valign=«top»></td>

<td width=«410» height=«53» valign=«top»><table border=«1» width=«100%» cellspacing=«0»

cellpadding=«0»>

<tr>

<td width=«100%»><form name=«GuestBook» method=«POST» action=«add_guestbook.pl»>

<div align=«left»><p><small>Я, <input type=«text» name=«Name» size=«20»></small>, <small>по

профессиипростой </small><input type=«text» name=«Work» size=«20»>, <small>посетив

данный сервер и ознакомившись с представленными

на нем материалами, хочу выразить свои чувства и

эмоции следующими приличными словами:</small></p>

</div><div align=«left»><p><small></small><input type=«radio» value=«Good» checked

name=«RadioButton»><small>мнепонравилось :-)</small></p>

</div><div align=«left»><p><small></small><input type=«radio» name=«RadioButton»

value=«Bad»><small>мненепонравилось :-( </small></p>

</div><div align=«left»><p><input type=«radio» name=«RadioButton» value=«Different»><small>мне

пофигу :-| </small></p>

</div><div align=«left»><p><small>В дополнение к сказанному хочу

так же сказать:</small></p>

</div><div align=«left»><p><textarea rows=«4» name=«Text» cols=«30»></textarea></p>

</div><div align=«left»><p><small>Прошу принять к рассмотрению

мое заявление и незамедлительно принять меры.

Решение по моему заявлению направить письменно

намойэлектронныйадрес </small><input type=«text» name=«Email»

size=«20»><small>.</small></p>

</div><div align=«center»><center><p><input src="../images/send.JPG" name=«Send»

alt=«Послать» border=«0» type=«image» WIDTH=«53» HEIGHT=«21»> <a

href=«read_guestbook.pl»><img src="../images/read.jpg" alt=«Почитать» border=«0»

WIDTH=«63» HEIGHT=«21»></a></p>

</center></div>

</form>

</td>

</tr>

</table>

</td>

<td width=«10» height=«53» valign=«top»></td>

</tr>

</table>

</div>

</body>

</html>

HTML

die;

}

# Теперь получаем входные данные.

&GetFormInput;

$Name = $field{'Name'};

$Work = $field{'Work'};

$RadioButton = $field{'RadioButton'};

$Text = $field{'Text'};

$Email = $field{'Email'};

$Send = $field{'Send'}; # это поле не используется

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

# Если нет — генерируем HTML страницу с просьбой заполнить нужные поля.

if ($Name eq '' || $Email eq '' || $Text eq '')

{

print <<HTML;

Content-type: text/html

<html>

<head>

<meta http-equiv=«Content-Type» content=«text/html; charset=windows-1251»>

<meta name=«GENERATOR» content=«Microsoft FrontPage 3.0»>

<title>Книга жалоб и предложений — ошибка</title>

</head>

<body background="../images/background_new.jpg">

<div align=«left»>

<table border=«0» width=«630» height=«49»>

<tr>

<td width=«200» height=«45»></td>

<td width=«430» height=«45»><p align=«center»><img src="../images/guestbook.GIF"

alt=«Книгажалоб» WIDTH=«258» HEIGHT=«60»></td>

</tr>

</table>

</div><div align=«left»>

<table border=«0» width=«630» height=«53» cellspacing=«0» cellpadding=«0»>

<tr>

<td width=«200» height=«260» valign=«top»><p align=«center»>

HTML

DoInclude(«D:/InetPub/wwwroot/_menu.htm»);

print <<HTML;

</p>

<p align=«left»></td>

<td width=«10» height=«53» valign=«top»></td>

<td width=«410» height=«53» valign=«top»><p align=«left»><small>Вынеуказали

свое имя, E-mail, либо не заполнили сам текст Вашего

отзыва. Вернитесь, пожалуйста, на страницу формы

и заполните требуемые поля.</small></p>

<p align=«center»><a href=«add_guestbook.pl»>Назад</a> </td>

</tr>

</table>

</div>

<table>

<tr>

<td width=«10» height=«53» valign=«top»></td>

</tr>

</table>

</body>

</html>

HTML

}

else # все данные правильно введены

{

# Если все поля заполнены правильно, то начинаем их обрабатывать.

$Text=~tr/\r\n/ /; #заменяем перевод строки на пробел

# Если в текстовом поле формы (text box) посетитель нажимал Enter,

# то нужно убрать символы перевода строки, чтобы можно было записать

# все поля формы в одну строку файла.

if ($Work eq '') {$Work=' '}; #если пусто — то пробел

# Если поле не заполнено, то оно равно пробелу.

$Name=~s/&/ /g;

$Work=~s/&/ /g;

$Text=~s/&/ /g;

$Email=~s/&/ /g;

# Если посетитель использовал символ &, то заменяем его на пробел,

# поскольку этот символ мы будем использовать для разделения наших полей в файле.

open(OutFile, ">>guestbook.txt") || die;

# Открываем файл для добавления.

$Time=localtime; #получаем время

# Получаем время заполнения гостевой книги.

$line=join('&', $Time, $Name, $Work, $RadioButton, $Text, $Email, $ENV{REMOTE_HOST});

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

# IP адрес посетителя, взятый из переменных окружения.

print OutFile "$line\n";

close OutFile;

# Записываем полученную строку в файл и закрываем его.

# Осталось только сказать посетителю спасибо.

# выводим сообщение о успехе

print «Content-type: text/html\n\n»;

print "<html>\n" ;

print "\n" ;

print "<head>\n" ;

print '<meta http-equiv=«Content-Type» content=«text/html; charset=windows-1251»>'."\n" ;

print '<meta name=«GENERATOR» content=«Microsoft FrontPage 3.0»>'."\n" ;

print "<title>Книга жалоб и предложений</title>\n" ;

print "</head>\n" ;

print "\n" ;

print '<body background="../images/background_new.jpg">'."\n" ;

print '<div align=«left»>'."\n" ;

print "\n" ;

print '<table border=«0» width=«630» height=«49»>'."\n" ;

print " <tr>\n" ;

print ' <td width=«200» height=«45»></td>'."\n" ;

print ' <td width=«430» height=«45»><p align=«center»>';

print '<img src="../images/guestbook.GIF" alt=«Книгажалоб» WIDTH=«258» HEIGHT=«60»></td>'."\n" ;

print " </tr>\n" ;

print "</table>\n" ;

print '</div><div align=«left»>'."\n" ;

print "\n" ;

print '<table border=«0» width=«630» height=«53» cellspacing=«0» cellpadding=«0»>'."\n" ;

print " <tr>\n" ;

print ' <td width=«200» height=«260» valign=«top»><p align=«center»>'."\n" ;

DoInclude(«D:/InetPub/wwwroot/_menu.htm»);

print ' <p align=«left»></td>'."\n" ;

print ' <td width=«10» height=«53» valign=«top»></td>'."\n" ;

print ' <td width=«410» height=«53» valign=«top»><p align=«center»><small>Вашиданные'."\n" ;

print " приняты. Спасибо.</small></p>\n" ;

print ' <p align=«center»><a href=«read_guestbook.pl»>';

print '<img src="../images/read.jpg" alt=«Почитать» border=«0» WIDTH=«63» HEIGHT=«21»></a> </td>'."\n" ;

print " </tr>\n" ;

print "</table>\n" ;

print "</div>\n" ;

print "\n" ;

print "<table>\n" ;

print " <tr>\n" ;

print ' <td width=«10» height=«53» valign=«top»></td>'."\n" ;

print " </tr>\n" ;

print "</table>\n" ;

print "</body>\n" ;

print "</html>\n" ;

}

# Не забываем подпрограмму разбора данных из формы.

sub GetFormInput {

(*fval) = @_ if @_ ;

local ($buf);

if ($ENV{'REQUEST_METHOD'} eq 'POST') {

read(STDIN,$buf,$ENV{'CONTENT_LENGTH'});

}

else {

$buf=$ENV{'QUERY_STRING'};

}

if ($buf eq "") {

return 0 ;

}

else {

@fval=split(/&/,$buf);

foreach $i (0… $#fval){

($name,$val)=split (/=/,$fval[$i],2);

$val=~tr/+/ /;

$val=~ s/%(..)/pack(«c»,hex($1))/ge;

$name=~tr/+/ /;

$name=~ s/%(..)/pack(«c»,hex($1))/ge;

if (!defined($field{$name})) {

$field{$name}=$val;

}

else {

$field{$name} .= ",$val";

#if you want multi-selects to goto into an array change to:

#$field{$name} .= "\0$val";

}

}

}

return 1;

}

Вот и все. Пример работы описанного скрипта можно посмотреть на treagraf.tasur.edu.ru/cgi-bin/add_guestbook.pl

read_guestbook.pl — чтениекниги

#! e:\perl5\perl

# Первая строка, как обычно

require «ssi-pl.pl»;

# Я использую навигационную панель в виде SSI-включения. Для этого используется модуль ssi-pl.pl

open(InFile, «guestbook.txt») || die;

# Открываем файл с записями гостевой книги.

@lines=<InFile>;

# Читаем строки в массив.

# Выдаем шапку HTML страницы.

print <<HTML;

Content-type: text/html

<html>

<head>

<meta http-equiv=«Content-Type» content=«text/html; charset=windows-1251»>

<meta name=«GENERATOR» content=«Microsoft FrontPage 3.0»>

<title>Книга жалоб и предложений — нам пишут</title>

</head>

<body background="../images/background_new.jpg">

<div align=«left»>

<table border=«0» width=«630» height=«49»>

<tr>

<td width=«200» height=«45»></td>

<td width=«430» height=«45»><p align=«center»><img src="../images/guestbook.GIF"

alt=«Книгажалоб» WIDTH=«258» HEIGHT=«60»></td>

</tr>

</table>

</div><div align=«left»>

<table border=«0» width=«630» height=«53» cellspacing=«0» cellpadding=«0»>

<tr>

<td width=«200» height=«260» valign=«top»><p align=«center»><small>

HTML

DoInclude(«D:/InetPub/wwwroot/_menu.htm»);

print <<HTML;

</p>

<p align=«left»></td>

<td width=«10» height=«53» valign=«top»></td>

<td width=«410» height=«53» valign=«top»><p align=«center»>Нампишут:</p>

<table border=«0» width=«100%» cellspacing=«0» cellpadding=«0»>

HTML

# Теперь выводим записи в невидимой (в смысле, рамка не видима) таблице.

# Чтобы свежие записи отображать первыми, обрабатываем массив строк с конца.

for ($i=$#lines; $i>=$[; $i--) #обрабатываем строки файла с конца

{

# Разделяем строку на части

@item=split('&', $lines[$i]); #разделяем на части

# Теперь заменяем HTML тэги в записи (на случай какого-нибудь хитрого юзера)

foreach (@item)

{

$_=~s/</</g;

$_=~s/>/>/g;

}

# Приступаем непосредственно к выводу записей в HTML

print "<tr>\n";

print '<td width=«100%»><dl>'."\n";

# В зависимости от поля, где посетителю предлагался выбор понравилось — не понравилось,

# рисуем картинку с веселой или грустной мордочкой соответственно. В качестве ALT тэга

# картинки пропишем IP адрес посетителя.

print '<dt><img src="../images/'.$item[3].'.gif" width=«31» height=«31» alt="';

priny $item[6].'" align=«absbottom»'."\n";

# Выводим остальные поля.

print 'align=«absmiddle»><small>'.' '.$item[4]."</small></dt>\n";

print '<dt><small>'.$item[1].', '.$item[2]."</small></dt>\n";

print '<dt><a href=«mailto:'.$item[5].'»><small>'.$item[5].'</small></a></dt>'."\n";

print '<dt><small>'.$item[0]."</small></dt>\n";

print "</dl>\n";

print "</td>\n";

print "</tr>\n";

}

# Осталось вывести окончание HTML

print <<HTML;

</table>

</td>

<td width=«10» height=«53» valign=«top»></td>

</tr>

</table>

</div>

</body>

</html>

HTML

close InFile;

# Закрываем файл с записями гостевой книги.

Список литературы

Александр Боровский. Практический Перл для начинающего.

еще рефераты
Еще работы по информатике