Perl является интерпретируемым языком, созданным программистом Лари Уоллом (Larry Wall) для обработки больших текстов и файлов и расшифровывается, как Practical Extraction and Report Language (язык для практического извлечения данных и составления отчетов). С помощью Perl вы, например, можете создать скрипт, который открывает один или несколько файлов, обрабатывает информацию и записывает результаты.
С изобретением World Wide Web, Perl оказался прекрасным средством для взаимодействия с web-серверами через Common Gateway Interface (CGI) - общий интерфейс взаимодействия. Команды Perl могут легко получить данные из формы HTML или другого источника и что-нибудь с ними сделать.
Perl достаточно гибок для обработки введенных данных. Например, если пользователь вводит информацию в регистрационную форму скрипт Perl может обработать ее многими способами, такими как:
Некоторые из этих примеров рассматриваются в нашем уроке.
Больше всего впечатляет то, что Perl может быть использован для создания web-страниц "на лету" в ответ на запрос или действие пользователя. Новая страница может быть
Эта возможность обеспечивает истинную интерактивность вашего узла. Такие скрипты позволят web-серверу автоматически реагировать на определенный набор запросов пользователя, предоставляя данные в требуемом пользователем виде.
Перед началом работы с Perl необходимо понять разницу между программой и скриптом. Оба из них используют набор инструкций для выполнения определенного задания, но программа скомпилирована в эффективный двоичный формат, что позволяет ей быстро выполняться на определенной платформе, в то время как скрипт хранится в оригинальном текстовом формате.
За счет того, что скрипты значительно короче программ, они выполняются тоже достаточно быстро.
За счет того, что скрипт не надо компилировать перед запуском он становится замечательным средством для быстрого создания и внесения исправлений в разработку интерактивных частей узла.
Существует несколько альтернатив использованию Perl:
Несмотря на это Perl на сегодняшний день является наиболее простым и быстрым и в тоже время очень мощным средством придания интерактивности вашему узлу.
Для запуска Perl вашей системе понадобится несколько компонент:
Существует много различных мест, где можно получить информацию о последних версиях Perl.
После того, как вы установили на своем компьютере необходимое ПО, нужно совершить несколько шагов для запуска Perl на вашем узле:
<form method=post action="/cgi-bin/scriptname.pl">
В общем случае любой Perl скрипт состоит из четырех ключевых частей:
Рассмотрим теперь описанные нами шаги на конкретном примере. От вас не требуется понимания каждой строки скрипта, все они будут объяснены ниже.
Создадим для простоты форму, содержащую всего одно поле и позволяющую пользователю зарегистрировать его имя. Напишем в редакторе следующий текст:
<html> <head> <title>Test Form</title> </head> <body> <form method=post action"cgi-bin/testform.pl"> <b>Введите Ваше имя: </b> <input name="user_name" value="" size=20> <input type="submit" value="Зарегистрировать"> </form> </body> </html>
Сохраните файл на диске.
Предложенный ниже скрипт берет введенные данные, сохраняет их в файле и показывает сообщение, содержащее ссылку на файл с сохраненным именем. Наберите в редакторе текст программы и сохраните в файле testform.pl в каталоге cgi-bin вашего web-сервера. Убедитесь, что первая строка программы содержит правильный путь к программе-интерпретатору (для определения местоположения программы на UNIX воспользуйтесь командой which perl, под Windows выполните поиск файла perl.exe). Убедитесь также, что путь к выходному файлу является корректным путем к области хранения документов web-сервера. В заключение исправьте URL на адрес вашего сервера.
#!/usr/local/bin/perl # <-- ПРОВЕРЬТЕ ЭТО # Read and parse input from the web form read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s/<!--(.|\n)*-->//g; $input{$name} = $value; } # Save the user output in a file $targetfile = "/usr/local/www/htdocs/names.html"; # <-- ПРОВЕРЬТЕ ЭТО open (NAMEFILE, ">>$targetfile"); print NAMEFILE "<h3>Имя: ",$input{'user_name'},"</h3>\n"; print NAMEFILE "<p><hr><p>\n"; close (NAMEFILE); # Send a message back to the user print "Content-Type: text/html\n\n"; print "<h3>Спасибо, что заполнили форму</h3>\nНажмите "; print '<a href="http://server-name/names.html">сюда</a>'; # <-- ЗАМЕНИТЕ ЭТО print ", чтобы увидеть Ваш ввод.\n";
Проверив скрипт визуально на наличие ошибок - отсутствие ";" в конце строк, наличие непарных скобок и кавычек и т.п., запустите скрипт для проверки прямо из командной строки, перейдя предварительно в каталог cgi-bin. Вот некоторые примеры того, как это делается:
./testform.pl /usr/local/bin/perl testform.pl c:\perl\perl.exe testform.pl
Если в скрипте содержатся ошибки, то вы увидите сообщение типа
syntax error at testform.pl line 18, near "open" Execution of testform.pl aborted due to compilation errors.
В этом случае проверьте текст около указанной строки. Помните, что причина ошибки может быть выше на несколько, иногда достаточно много, строк. Исправленный скрипт сохраните, и тестируйте так до тех пор, пока он не выдаст корректных выходных данных:
Content-Type: text/html <h3>Спасибо, что заполнили форму</h3> Нажмите <a href="http://server-name/names.html">сюда</a>, чтобы увидеть Ваш ввод.
Если скрипт работает сам по себе, вы можете оттестировать его с формой:
Спасибо, что заполнили форму
Нажмите сюда, чтобы
увидеть Ваш ввод.
Это и есть страница, сгенерированная скриптом "на лету". Если вы получили сообщение об ошибке сервера, проверьте правильность расположения скрипта и правильность значения параметра action в тэге form.
Имя: Новиков
Если вы не видите этого, проверьте правильность пути в переменной $targetfile и правильность URL в предпоследней строке скрипта. В противном случае форма и скрипт правильно работают вместе. Вы успешно создали первое web-приложение.
Далее мы рассмотрим четыре части созданного нами скрипта более внимательно.
Как уже было сказано, первая часть скрипта содержит настройки,
включающие в себя несколько элементов. Первая строка определяет путь к
программе-интерпретатору:
#!/usr/local/bin/perl для
UNIX
или
\Program Files\Perl5\perl.exe для Win32
Также в начале скрипта вы, для удобства, можете разместить комментарий о том, для чего предназначен этот скрипт.
Комментарии могут располагаться в любом месте программы и начинаются с
символа #:# Это комментарий
илиopen (NAMEFILE, ">$testfile"); #Открываем файл для записи...
Также хорошей манерой является определение в начале скрипта всех
констант и глобальных переменных. (Советую все пути прописывать в виде
переменных, особенно если программа содержит более 50 строк, для удобства
изменения местоположения файлов). Например:$homepage = "http://server_name/home/index.html";
Все обычные переменные в Perl начинаются с символа $. Существует много других видов переменных, таких как массивы и т.п.
Все строки программы кроме первой и комментариев должны заканчиваться на ";".
Теперь необходимо "считать" введенные пользователем данные в переменные Perl. После того как пользователь нажмет кнопку Submit в форме браузер посылает серверу имя скрипта и данные, взятые из формы. Данные передаются скрипту на стандартный вход.
Предположим, что форма содержит следующие поля:
Имя поля в форме |
Имя, определенное параметром name="xxx" в тэге поля |
Данные пользователя |
Имя: |
user_name |
Andy Novikov |
Компания: |
co_name |
TeleSputnik |
Телефон: |
phone |
(812) 123-45-67 |
В этом случае данные будут посланы скрипту в следующем
формате:
user_name=Andy+Novikov&co_name=TeleSputnik&phone=(812)+123-45-67
Perl скрипт должен разобрать эту строку по частям и сохранить в
переменных для дальнейшей обработки. Строки, производящие эти действия
достаточно стандартны:read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
Эта строка читает данные со стандартного входа и помещает их в переменную $buffer. Длина строки передается скрипту через переменную окружения CONTENT_LENGTH.
Как только данные помещены в переменную $buffer вы можете разбить их на
отдельные переменные с соответствующими им значениями:@pairs = split(/&/, $buffer);
Теперь мы получили массив @pairs со следующими строковыми
переменными:
[1] user_name=Andy+Novikov
[2]
co_name=TeleSputnik
[3] phone=(812)+123-45-67
Теперь нам необходимо разбить эти строки на пары
параметр-значение:foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /; # заменяем плюсы на пробелы
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/<!--(.|\n)*-->//g;
$input{$name} = $value;
}
Таким образом вы получаете массив переменных, индексом в котором является значение параметра name поля формы, а значением - данные, введенные в соответствующее поле.
Следующим шагом является обработка данных. Но как? Все зависит от того, что вы хотите сделать с данными. В нашем примере мы на основе полученных данных создаем новый HTML документ. Ниже мы рассмотрим несколько простых примеров того, что можно сделать с полученными данными. Обратите внимание, что мы не предпринимаем попыток проверить правильность (validate) содержимого полей. Хотя в реальных скриптах это является желательным, а иногда и необходимым действием.
Одно из действий, которое вы можете совершить над данными, это записать их в файл. Perl предоставляет набор функций для открытия, обработки и закрытия файлов. Таким образом вы можете создать новый HTML документ, добавить данные в уже существующий HTML документ или сохранить данные в текстовом файле для дальнейшей обработки.
Функция открытия файла выглядит следующим образом:open (HANDLE, "name"); # Открыть файл для чтения
open (HANDLE, ">name"); # Открыть файл для записи
open (HANDLE, ">>name"); # Открыть файл для добавления в конец
HANDLE является любым временным именем, который вы будете использовать
как идентификатор файла при проведении операций. Как только файл открыт,
вы можете писать в него, используя функцию print:print HANDLE "Этот текст будет помещен в файл как есть.\n";
print HANDLE "В этом случае переменная ",$variable," будет помещена в текст.";
print HANDLE "Переменную $variable можно помещать в текст и так.\n";
print HANDLE "Кавычки и др. Спецсимволы \; надо \"подсекать\".\n";
После завершения операций с файлом необходимо его закрыть:close (HANDLE);
После этого все записанные данные будут сохранены на диск.
Перед осуществлением запись в файл, вы должны убедиться, что web-сервер имеет доступ к директории, в которой находится файл и имеет права на запись в этот файл.
Обратите внимание: функция close должна располагаться как можно ближе к последней функции записи в файл. Это обусловлено тем, что web-сервер выполняется в многопользовательской среде, и скрипт может запускаться одновременно несколькими пользователями. При открытии файла на запись он (файл) блокируется и другие экземпляры скрипта не смогут его открыть, что вызовет задержку в выполнении запроса.
Следующий пример может показаться на первый взгляд сложным, но все что он делает, это пишет некоторую информацию в файл.
В связи с тем, что мы создаем web-страницу файл содержит тэги HTML вместе с обычным текстом. Помните, что \n просто вставляет перевод строки в текст для удобства последующего просмотра созданного файла.
Все входные данные из формы содержатся в переменных $input{field_name}. При печати такие переменные должны выноситься за кавычки и отделяться запятыми.
# Определяем переменную, содержащую путь к записываемому файлу $newfile = "c:\webserver\htdocs\mynewpage.html"; # Открываем файл, используя идентефикатор USERINFO open (USERINFO, ">$newfile"); # Формируем содержимое print USERINFO "<html>\n<head>\n"; print USERINFO "<title>Информация о регистрации</title>\n</head>\n"; print USERINFO "\n<body>\n<h3>Данные регистрации:</h3>"; print USERINFO "<p><hr></p>\n<p>\n"; print USERINFO "Имя: ", $input{'user_name'},"\n<br>"; print USERINFO "Компания: ", $input{'co_name'},"\n<br>"; print USERINFO "Телефон: ", $input{'phone'},"\n</p>\n<p><hr></p>\n"; print USERINFO "<!-- NEW INSERTS GO HERE -->\n\n</body>\n</html>"; # Закрываем файл close (USERINFO);
Запись в существующий файл проста, когда вы хотите добавить новую информацию в конец файла. Например, для добавления данных о новом пользователе в созданный выше файл вам потребуется следующий скрипт:
# Определяем переменную, содержащую путь к записываемому файлу $targetfile = "c:\webserver\htdocs\mynewpage.html"; # Открываем файл, используя идентификатор NEWINFO open (NEWINFO, ">>$targetfile"); # Добавляем новые данные в файл: print NEWINFO "\n\n"; print NEWINFO "Имя: ", $input{'user_name'},"\n<br>"; print NEWINFO "Компания: ", $input{'co_name'},"\n<br>"; print NEWINFO "Телефон: ", $input{'phone'},"\n</p>\n<p><hr></p>\n"; close (NEWINFO);
Более сложной задачей является вставка новых данных в середину файла.
Обратите внимание, что в первом примере мы вставили в файл линию
комментария, выглядящую следующим образом:<!-- NEW INSERTS GO HERE -->
Этот комментарий будет служить нам меткой места, в которое нужно вставлять новые данные. Данный пример содержит не совсем изящное решение, но прост в реализации и понимании. Он использует временный файл, хотя можно обойтись и без него:
# Определяем переменную, содержащую путь к исходному файлу $origfile = "/pathname/originalfile.htm"; # Определяем переменную, содержащую путь к временному файлу $newfile = "/pathname/newfile.htm"; open(INFILE, "<$origfile"); open(OUTFILE, ">$newfile"); while ($line = <INFILE>) { printf OUTFILE $line; if ($line =~ /<!-- NEW INSERTS GO HERE -->/i) { # Добавляем новые данные в файл: print OUTFILE "\n\n"; print OUTFILE "Имя: ", $input{'user_name'},"\n<br>"; print OUTFILE "Компания: ", $input{'co_name'},"\n<br>"; print OUTFILE "Телефон: ", $input{'phone'},"\n</p>\n<p><hr></p>\n"; } } # Закрываем файлы close(INFILE); close(OUTFILE); # Удаляем исходный файл и переименовываем новый в исходный unlink($origfile); rename($newfile, $origfile);
Иногда вам может потребоваться, чтобы данные введенные в форму были посланы по некоторому адресу электронной почты.
Для этого вам потребуется программа посылки почты с интерфейсом командной строки. Под UNIX это может быть sendmail или mail. В данном примере данные посылаются с помощью программы sendmail. Вместо записи в файл мы используем запись в специально открытый канал (pipe):
# Адрес e-mail $sendto = "webmaster\@telesputnik.ru"; # Открываем канал open (MAIL, "| /usr/bin/sendmail $sendto") # Печатаем в канал в специальном формате print MAIL "From: Web-сервер\n"; print MAIL "To: $sendto\n"; print MAIL "Subject: Ввод новых данных"; print MAIL "Кто-то воспользовался формой для ввода новых данных"; print MAIL "Вот что он ввел:"; print MAIL "Имя: ", $input{'user_name'},"\n"; print MAIL "Компания: ", $input{'co_name'},"\n"; print MAIL "Телефон: ", $input{'phone'},"\n "; # Посылаем письмо, закрывая канал close (MAIL);
Последней важной частью Perl скрипта является посылка результата обратно пользователю. Это достигается тем же print, но без идентификатора файла или канала. Все, что печатается на стандартный выход формирует текущий документ в окне браузера. Например:
print "Content-Type: text/html\n\n"; print "<html>\n<head>\n<title>Спасибо</title>\n</head>"; print "<body>\n<h1>Спасибо за заполнение формы</h1>"; print "Мы получили ваше имя, место работы и телефон,"; print " которые вы видите ниже:<br>\n"; print "Имя: ", $input{'user_name'},"\n<br>"; print "Компания: ", $input{'co_name'},"\n<br>"; print "Телефон: ", $input{'phone'},"\n</p>\n<p><hr></p>\n"; print "</body>\n</html>";
Обратите внимание на первую строку. Эта строка содержит информацию о типе возвращаемых данных. Двойной перевод стоки при этом обязателен. Эта страница будет возвращена пользователю почти сразу после нажатия им кнопки Submit.
Учтите, что это всего лишь один из многих примеров того, какой может быть страница "на лету". В принципе вы можете формировать HTML документ любой формы и содержания.