Практический Перл для начинающего
Данная работа написана для людей, которым в силу непреодолимых обстоятельств приспичило срочно изучить Перл. Для меня таким обстоятельством стало то, что мой компьютер стал 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-кодов в шестнадцатиричной форме, перед которыми ставится знак (%). Пример: http://treagraf.tasur.edu.ru/cgi-bin/B_price.pl?Category=%C2%E8%E4%E5%EE&Description=%E0%E1%E2%E3 Это значит: http://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" height="49"> <tr> <td height="45"></td> <td height="45"><p align="center"><img src="../images/guestbook.GIF" alt="Книга жалоб" HEIGHT="60"></td> </tr> </table> </div><div align="left"> <table border="0" height="53" cellspacing="0" cellpadding="0"> <tr> <td height="260"
<p align="center">
HTML DoInclude("_menu.htm"); # Это SSI-включение навигационной панели. print <<HTML; </p> <p align="left"></td> <td height="53" <td height="53" border="1" cellspacing="0" cellpadding="0"> <tr> <td 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" HEIGHT="21"> <a href="read_guestbook.pl"><img src="../images/read.jpg" alt="Почитать" border="0" HEIGHT="21"></a></p> </center></div> </form> </td> </tr> </table> </td> <td height="53" </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" height="49"> <tr> <td height="45"></td> <td height="45"><p align="center"><img src="../images/guestbook.GIF" alt="Книга жалоб" HEIGHT="60"></td> </tr> </table> </div><div align="left"> <table border="0" height="53" cellspacing="0" cellpadding="0"> <tr> <td height="260" align="center">
HTML DoInclude("D:/InetPub/wwwroot/_menu.htm"); print <<HTML;
</p> <p align="left"></td> <td height="53" <td height="53" align="left"><small>Вы не указали свое имя, E-mail, либо не заполнили сам текст Вашего отзыва. Вернитесь, пожалуйста, на страницу формы и заполните требуемые поля.</small></p> <p align="center"><a href="add_guestbook.pl">Назад</a> </td> </tr> </table> </div> <table> <tr> <td height="53" </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" height="49">'."\n"; print " <tr>\n"; print ' <td height="45"></td>'."\n"; print ' <td height="45"><p align="center">'; print '<img src="../images/guestbook.GIF" alt="Книга жалоб" HEIGHT="60"></td>'."\n"; print " </tr>\n"; print "</table>\n"; print '</div><div align="left">'."\n"; print "\n"; print '<table border="0" height="53" cellspacing="0" cellpadding="0">'."\n"; print " <tr>\n"; print ' <td height="260" align="center">'."\n"; DoInclude("D:/InetPub/wwwroot/_menu.htm"); print ' <p align="left"></td>'."\n"; print ' <td height="53"; print ' <td height="53" 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" HEIGHT="21"></a> </td>'."\n"; print " </tr>\n"; print "</table>\n"; print "</div>\n"; print "\n"; print "<table>\n"; print " <tr>\n"; print ' <td height="53"; 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; } Вот и все. Пример работы описанного скрипта можно посмотреть на http://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" height="49"> <tr> <td height="45"></td> <td height="45"><p align="center"><img src="../images/guestbook.GIF" alt="Книга жалоб" HEIGHT="60"></td> </tr> </table> </div><div align="left"> <table border="0" height="53" cellspacing="0" cellpadding="0"> <tr> <td height="260" align="center"><small>
HTML DoInclude("D:/InetPub/wwwroot/_menu.htm"); print <<HTML; </p> <p align="left"></td> <td height="53" <td height="53" align="center">Нам пишут:</p> <table border="0" 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" 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 height="53" </tr> </table> </div> </body> </html> HTML close InFile; # Закрываем файл с записями гостевой книги. Список литературы Александр Боровский. Практический Перл для начинающего.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|