
- •Язык программирования perl
- •Perl как язык программирования
- •История perl
- •Perl - интерпретируемый язык программирования
- •Богатство возможностей языка perl
- •Использование perl
- •Использование perl как фильтра данных
- •Использование языка perl как шлюза безопасности
- •Frontend-программы для связи с базой данных
- •Использование языка perl для написания cgicкриптов.
- •Знакомство с языком perl
- •Установка perl
- •Использование отладчика perl
- •Типы данных в perl
- •Переменные
- •Скалярные переменные
- •Массивы
- •Роль контекста аля переменных скалярного и векторного типа
- •Ассоциативные массивы
- •Операторы perl
- •Арифметические операторы
- •Побитовые операторы
- •Операторы сравнения
- •Логические операторы
- •Строковые операторы
- •Операторы присваивания
- •Операции для работы со списками
- •Операторы для работы с файлами
- •Приоритеты выполнения операторов
- •Конструкции языка perl
- •Простые и составные операторы
- •Условные операторы
- •Оператор unless
- •Оператор do
- •Циклы и ветвления
- •Цикл until
- •Циклы for и foreach
- •Оператор безусловного перехода goto
- •Модификаторы операторов
- •Генерация динамических выражений с помощью функции eval
- •Подпрограммы
- •Библиотека подпрограмм
- •Использование пакетов для изоляции подпрограмм
- •Обработка строк
- •Функция chop
- •Функция index
- •Функция length
- •Функция substr
- •Функция join
- •Функция split
- •Функции для обработки списков
- •Функция reverse
- •Функция sort
- •Функции работы с массивами
- •Функции push и pop
- •Функция shift
- •Функция unshift
- •Функция splice
- •Функция scalar
- •Функция grep
- •Функции обработки ассоциативных массивов
- •Функция keys
- •Функция values
- •Функция each
- •Функция delete
- •Аргументы командной строки
- •Доступ к переменным окружения
- •Файловый ввод и вывод
- •Открытие файлов и других потоков
- •Построчное чтение и запись данных
- •Чтение и запись блоков данных
- •Обработка бинарных данных
- •Хранение бинарных данных
- •Распаковка строк бинарных данных в переменные языка perl
- •Упаковка данных в бинарные строки
- •Работа с каталогами
- •Открытие, чтение и закрытие каталогов
- •Форматированный вывод
- •Использование функции print
- •Форматированный вывод данных функцией printf
- •Вызов внешних программ из скрипта на языке perl
- •Регулярные выражения
- •Обзор регулярных выражений
- •Синтаксис регулярных выражений
- •Использование регулярных выражений для поиска по ключевымсловам
- •Использование регулярных выражений для анализа входных данных
- •Регулярные выражения для поиска и замены строк
- •Создание скриптов cgi с помощью perl
- •Вызов cgi-скрипта
- •Вызов сgi-скрипта в системе unix
- •Вызов скрипта на языке perl из dos и windows
- •Создание текста и html-документа с использованием языка perl
- •Добавление в документ динамических свойств
- •Доступ к строке запросов
- •Декодирование html-форм с помощью метода post
Добавление в документ динамических свойств
Если бы возможности CGI-скриптов ограничивались созданием статических форм, то это было бы грустно. Настоящая сила CGI состоит в придании Webстраницам динамики. В главе 11 вы рассматривали программу на языке C++, которая создает скрипт, выводящий наэкран значения переменных окружения. Следующий скрипт на языкеPerl решает идентичную задачу. Тем не менее, вы убедитесь, насколько проще выглядит программа на языке Perl, чем аналогичнаяС++ версия, показанная в главе 11:
print <<HTML;
Content-type: text/html
<HTML>
<HEAD><TITLE>Echo Environment Variables </TITLE></HEAD>
<BODY>
<H3><CENTER>
Environment Variables:<HR>
</CENTER></H3>
for $env (sort keys %ENV)
{
print "<LI>$env is $ENV{$env}<BR>";
}
print "</BODY></HTML>\n"
Этот пример создает статический заголовок, и затем выводит значения переменных окружения скрипта, используя форматированныйHTML-документ. Скрипт показывает, как использовать конструкцию<здесь-документ> совместно с традиционной функцией print.
Доступ к строке запросов
В главе 11 вы видели, что простым способом передачи данныхCGI в скрипт является использование строки запросов. Броузер передает данные HTTP-серверу как часть URL. В свою очередь серверрассматривает все, что следует за знаком вопроса (?) в URL, какстроку запроса. CGI-скрипт может получить доступ к строке запросов двумяспособами. Либо сервер передает строку запросов скрипту, используя аргументы командной строки, либо сервер присваивает значение строки запросов переменной окружения QUERY_STRING. Например, можно возвратиться к рассмотренному выше скрипту, которыйвыводит на экран значения переменных окружения, и вызвать скрипт,используя строку запросов.
ДЕКОДИРОВАНИЕ ФОРМ HTML С ИСПОЛЬЗОВАНИЕМ МЕТОДА GET
Как вы увидели, использование подсказки ISINDEX для создания одиночного запроса достаточно просто. Но для получения отпользователя больше чем одного значения необходимо использоватьформы. Следующий скрипт на языке Perl генерирует форму. Используяметод GET, скрипт дает команду броузеру послать значения запросакак часть URL, так же как при использовании ISINDEX. Разница между использованием GET и ISINDEX состоит в том, что при использовании метода GET броузер может соединить несколько величин полейв одну строку запросов, разделяя поля с помощью амперсанда (&).Для того чтобы скрипт мог определять значения полей, броузервключает имена полей в строку запроса. Например, если база данных содержит три поля (имя, возраст и день рождения) с такимизначениями (Bob, 27, 11-1-68), то строка запросов будет содержать значения полей в следующем формате:<name=Bob&age==27&birthday=l 1-1-68>. В следующем примере скриптдекодирует поля и выводит на экран их значения с помощью создания HTML-формы:
($cgi_bin, $cgi_script) = ($0 =~ m:(.*)[/\\](.*):);
$query = $ENV{QUERY_STRING};
if ($query eq '')
{
# сгенерируем форму
print <<FORM;
Content-type: text/html
<HTML>
<HEAD><TITLE>Sample GET Form </TITLE></HEAD>
<BODY>
What is your query? <P>
<FORM METHOD="GET" ACTION="$cgi_script">
A checkBox. <BR>
<INPUT TYPE="checkbox" NAME="chek" VALUE="on"><P>
A radio button set. <BR>
<INPUT TYPE="radio" NAME="button" VALUE="1"> 1<BR>
<INPUT TYPE="radio" NAME="button" VALUE="2"> 2<BR>
<INPUT TYPE="radio" NAME="button" VALUE="3"> 3<P>
A data entry field<BR>
<INPUT NAME="field"><P>
Send the data.<BR>
<INPUT TYPE="submit">
</FORM>
</HTML>
FORM
}
else {
# распечатаем результаты
print "Content-type: text/html\n\n";
print "<HTML>\n";
print "<HEAD><TITLE>GET Form Result</TITLE></HEAD>\n"
print "<BODY>\n";
print "Your query values:<P>\n";
@fields = split('&', $query);
forech (@field) {
Switch: {
/^check=(.*)/ && do {
$check = $1;
last Switch;
};
/^button=(.*)/ && do {
$button = $1;
last Switch;
};
/^field=(.*)/ && do {
$field = $decode(1);
last Switch;
};
}
}
print "Check Box: $check<BR>\n";
print "Radio Button: $button<BR>\n";
print "Data Field:", &html($field), "<BR>\n";
print "<HTML>\n";
}
sub decode{
local ($value) = @_;
$value =~ s/\+/ /g;
$value =~ s/%([0-9A-H]{2})/pack('C',hex($1))/eg;
return $value;
}
sub html {
local ($value) = @_;
$value =~ s/</</g;
$value =~ s/>/>/g;
return $value'
}
Обратите внимание на первую строку скрипта:
($cgi_bin, $cgi_script) = ($0 =~ m:(.*)[/\\](.*):);
Это выражение выглядит похожим на аналогичное выражение впредыдущем примере. Однако в данном случае скрипт разделяет путьна каталог и имя файла. В этом примере один и тот же скрипт создает форму и обрабатывает ее вывод, что достаточно нетрудно выполнить. Такой способ рекомендуется для обработки форм, потомучто концентрирует всю обработку в одном месте. Скрипт определяет, создавать ли форму или обработать запрос,в зависимости оттого, поступил ли запрос от пользователя. Для обработки строки запросов скрипт разделяет запрос на поля, используя функцию split. Далее скрипт сравнивает поля запроса сожидаемыми именами полей. Рассмотрим следующий пример:
forech (@field) {
Switch: {
/^check=(.*)/ && do {
$check = $1;
last Switch;
};
Обычная форма цикла foreach включает переменную {$VAR). Еслицикл foreach опускает эту переменную, то Perl использует переменную по умолчанию $_. Аналогично, оператор регулярного выраженияобычно выглядит следующим образом $VAR=~/PATTERN/. Если переменная в выражении опущена, Perl использует $_ как переменную поумолчанию, в результате чего цикл и регулярное выражение соответствуют друг другу. Однако если слишком полагаться на переменныепо умолчанию, то код на языке Perl может получиться неясным. Вданном же случае использование переменных, определенных по умолчанию, делает код более коротким и лучше читаемым. Далее обратите внимание на регулярное выражение, имеющееформу /^field=(. *)/. Данное выражение указывает на необходимость начать поиск от начала строки, что предотвращает совпадения в середине имени другого поля. Иными словами, имя поля и знакравенства (=) должны соответствовать сами себе. Остающаяся частьрегулярного выражения соответствует значению поля и извлекает егов переменную $1. Поскольку $1 представляет собой временную переменную, то скрипт копирует ее в переменную с именем для каждогополя. Скрипт использует подпрограмму decode для декодированиясимволов из полей, которые были закодированы броузером. Регулярные выражения, используемые подпрограммой декодирования, рассматривались в предыдущем примере. Наконец, скрипт использует подпрограмму html, чтобы закодировать значения данных для вывода их в тексте HTML. Скрипт можетпослать большую часть текста броузеру в виде HTML-документа безвыполнения какой-либо обработки. Однако поскольку HTML использует угловые скобки (<>) для кодирования НТМL-входов, скриптдолжен закодировать эти скобки, используя последовательности HTML< и >.