Приложение 3. Основы CGI/Perl

Программы, написанные на языке скриптов Perl, синтаксически похожи на программы, написанные на языке Cи. Рассмотрим простой пример вывода строк:

#!/usr/local/bin/perl –w

print("Hello, world\n"); #пример3.1-вывод строк

print "I live in Minsk,\n", "I work hire", "\n";

print ('Hello, world\n');

Будет выведено:

Hello, world

I live in Minsk,

I work hire

Hello, world \n

Программы main(), как в языке Си, здесь нет. Комментарием в Perl является все, что следует за «решеткой» (#), вплоть до конца строки. Строка в одинарных ковычках рассматривается как массив символов, при этом символы \n будут выведены как обычные символы, а не как символ конца строки.

В системе UNIX при вызове Perl через CGI первая строка должна иметь вид комментария, в котором системе указывается путь к интерпретатору perl.exe. Аналогично, в системе Windows указывается свой путь, в котором прямой слэш ‘/’ может быть заменен на обратный ‘\’, например c:\perl5\bin\perl.

Чтобы выполнить программу, создаем файл pr31.pl и наберем строку вызова интерпретатора: perl pr31.pl

Интерпретатор языка перед выполнением компилирует программу в свой внутренний формат. Поэтому после ее запуска невозможно получить сообщение о синтаксической ошибке — это происходит только в процессе отладки программы.

Рассмотрим второй пример ввода и вывода значений строковых переменных:

#!/usr/local/bin/perl -w

#пример3.2- ввод и вывод строк

# -w режим отображения предупреждений об ошибках

print "What is yure name?:";

$who =;

$where = 'Минск';

print "My name is $who,\n"; # представимся

print "I live in \t$where\n",

Будет выведено:

What is yure name?:valera

My name is valera,

I live in Минск

Для ввода строкового значения используется дескриптор стандартного файла . Если строка еще не образована, то Perl останавливается и ждет до тех пор, пока не будут введены информация и вслед за ней символ перехода на новую строку.

Типы данных

Perl оперирует следующими типами данных - скалярами, массивами, ассоциативными массивами (хешами). Особенностью Perl является то, что типы применяемых переменных не объявляются.

Их названия начинаются со знака $ - для скалярных переменных, @ -для массивов, % - хешей. Имена $varName и @varName различны.

Скалярные переменные могут принимать числовые и строковые значения, например



#Пример 3.3 : Вывод значений переменных

$str=”Результат:”;

$a = 2;

$b = 6;

$c = $a . $b; # ”.” — операция конкатенации двух строк

$d = $c / 2;

print $str, $d; # — результат равен 13

Будет выведено:

Результат:13

Массив — это список скаляров. Каждый элемент массива — это скалярная переменная, которой можно присваивать значение. Все массивы в языке Perl— динамические. О проблемах распределения памяти заботится интерпретатор. Рассмотрим пример:

#Ghbvth 3.4 : Вывод значений массивов

@emptyArray = ();

@numberArray = (12, 014, 0x0c, 34.34, 23.3E-3);

@stringArray = ("This", "is", 'an', "array", 'of', "strings");

@mixedArray = ("This ", 10, " is ", 'a', " mixed array ", ' of ', " items");

print "Here is an empty array:" . @emptyArray ."\n";

print @numberArray; print "\n";

print @stringArray; print "\n";

print @mixedArray; print "\n";

Будет выведено:

Here is an empty array:0

12121234.340.0233

Thisisanarrayofstrings

This 10 is a mixed array of items

Здесь символ "\n" выводится отдельно от массива. Если вместо этого использовать контактенацию и вывести print @numberArray . "\n";, то Perl истолкует @numberArray в скалярном контексте и выведет не элементы массива, а их число. Так и происходит вывод массива @emptyArray, в результате чего выводится число элементов 0.

В следующем примере массив используется в скалярном контексте в котором значением массива является число элементов.

@array = (1..5);

$numberOfElements = @array;

$doubleTheSize = 2 * @array;

print "The number of array elements is: " . $numberOfElements . "\n";



print "Double the number of array elements is: " . $doubleTheSize . "\n";

Будет выведено:

The number of array elements is: 5

Double the number of array elements is:10

Два массива можно объединить в одном:

@smallArrayOne = (5..10);

@smallArrayTwo = (1..5);

@largeArray = (@smallArrayOne, @smallArrayTwo);

print @largeArray;

Будет выведено:

Как и в C++, нумерация элементов массива начинается с нуля, однако здесь можно использовать отрицательные индексы, чтобы вести отсчет от конца массива. Например:

@array = (1..5);

print @array; print "\n";

print $array[-1]; print $array[-2];

print $array[-3]; print $array[-4];

print $array[-5]; print "\n";

Будет выведено:

Можно использовать подмассивы данного массива:

@array = ("One", "Two", "Three", "Four");

($first, $third) = @array[0, 2];

@half = @array[2, 3];

print("\@array=@array\n");

print("\$first=$first \$third=$third\n");

print("\@half=@half\n");

@array[0, 3] = @array[3, 0];

print("\@array=@array\n");

Будет выведено:

@array=One Two Three Four

$first=One $third=Three

@half=Three Four

@array=Four Two Three One

В отличие от других языков программирования, в массиве на Perl можно объединять скаляры разных типов данных. В следующем примере массивы объединяются в результирующий массив.

@A=(1,2,3);

@B = (4, 5, 6);

@C = (7, 8, 9);

@D = (@A, @B, @C);

print @D;

Результирующий массив D будет содержать числовые значения от 1 до 9

Встроенная функция qw() используется для объединения нескольких скалярных значений в массив например:

@passwords = qw(pas1 pas2 pas3);

Проведя такую операцию, затем можно обращаться к каждому из скаляров с помощью индексных ссылок. В рассматриваемом примере $passwords[0] имеет значение pas1, $passwords[1] — pas2, а $passwords[2] —pas3.

Вcтроенная функция sort(() использует массивы как аргументы и возвращает массив, в отсортированном виде. Результатом операции print sort(‘Beta’,’Gamma’,’Alpha’); будет последовательность AlphaBetaGamma. Функция join() имеет два входных параметра — строку и массив строк. Она возвращает строку, которая состоит из всех элементов массива, разделенных значением входной строки, т. е. print join (‘:’,’Name’,’Address’,’Phone’); и выдает на печать Name : Address : Phone. Функцию push() можно использовать, чтобы добавить к уже существующему массиву какой-нибудь элемент, не создавая при этом дополнительный массив. Например:

#Пример 3.10 : добавление элемента в массив

@b = (”Beta”, ”Gamma”, ”Alpha”);

push @b, ”Tetta”; # добавим в массив @b новый элемент

@w = sort @b; # отсортируем массив @b по алфавиту

$i=0; # инициализируем переменную $c

foreach (@w) {

print ”$w[$i]\n”; # выведем отсортированные значения

$i++;

}

Будет выведено:

Alpha

Beta

Gamma

Tetta

Как ранее указывалось, дескриптор возвращает в скалярном виде значение введенной строки. Примененный массиву, он каждому его отдельному элементу присваивает значение очередной введенной строки, пока не будет введен признак конца файла Ctrl+Z. Таким образом, если ввести три строки и операцию конца файла [Ctrl + Z], то массив будет состоять из трех элементов, которые являются строками и заканчиваются символами перехода на новую строку.

#!/usr/local/bin/perl -w

#пример3.12- ввод и вывод строк

print "Enter an array elements:";

@a =;

print "Array: @a \n";

Будет выведено:

Enter an array elements: aaaa

bbbb

cccc

Ctrl+Z

Array: aaaa

bbbb

cccc

Ассоциированные массивы

В ассоциированных массивах или кэшах в качестве индекса можно использовать любой скалярный тип данных.

%associativeArray = ("Jack A.", "Dec 2", "Joe B.",

"June 2", "Jane C.", "Feb 13");

$associativeArray{"Jennifer S."} = "Mar 20";

print "Joe's birthday is: " . $associativeArray{"Joe B."} . "\n";

print "Jennifer's birthday is: " . $associativeArray{"Jennifer S."} . "\n";

Будет выведено:

Joe's birthday is: June 2

Jennifer's birthday is: Mar 20

Ассоциированные массивы, так же как и обычные, представляют собой набор скалярных данных, отдельные элементы которого выбираются по индексному строковому значению. Элементы АМ не упорядочены, поэтому использовать их несколько сложнее, чем обычные, поскольку все строки (ключи) необходимо хранить вместе со значениями, на которые они ссылаются, например

%fruit=(”Green”,”Apple”,”Orange”,”Orange”,”Yellow”,”Banana”);

print $fruit{”Yellow”};

В результате из-за структуры АМ «ключ, значение», получается «Banana». Ключом также является «Green», которому будет соответствовать элемент массива «Apple».

Ассоциативные массивы (АМ) упрощают работу программистов с базами данных (БД). Для лучшего понимания использования АМ следует сопоставить ключи с ID в таблицах реляционных баз данных, которые представляют собой практически одно и то же. Рассмотрим пример.

%Folk = ('BG', 'Bill Gates',

'PR', 'SuperProgramer',

'DS', 'Djon Smith');

%State = ('BG', 'California',

'PR', 'Minsk',

'DS', 'Washington' );

%Job = ('BG', 'work in Microsoft',

'PR', 'work as programmer',

'DS', 'work as writer');

foreach $person ('PR', 'BG', 'DS') {

print "My name is $Folk{$person},\n",

"I live in $State{$person},\n",

"I $Job{$person} there.\n\n";

}

Будет выведено:

My name is SuperProgramer,

I live in Minsk,

I work as programmer there.

My name is Bill Gates,

I live in California,

I work in Microsoft there.

My name is Djon Smith,

I live in Washington,

I work as writer there.

Содержимое массивов можно представить и в другой форме, например : %Job = (‘BG’ => ‘work in Microsoft’, ‘PR’ => ‘work as programmer’, ‘DS’ => ‘work as writer’);

Индексы и элементы массива можно заключать как в апострофы, так и в кавычки. Чтобы перебрать все значения АМ, можно использовать оператор цикла foreach. Можно обращаться к ключам и значениям с помощью операторов keys и values.

Специальный ассоциативный массив %ENV хранит содержимое всех переменных, индексированных по имени. Так, %ENV{‘PATH’} возвращает текущее значение пути поиска. Существует также функция each, приводящая список, который состоит из двух элементов — ключа и значения. При каждом следующем вызове она возвращает новую пару, например

while (($key,$value) = each %ENV) {

print ”$key = $value\n”;

}

Строки

Двойные ковычки в строках

@array = (1..5);

print "@array\n";

Будет выведено:

1 2 3 4 5

Если вы хотите вывести значение переменной, а затем добавить символы в конце с помощью кода:

$word = "large";

print "He was a $wordr fellow.";

Будет выведено:

He was a fellow.

Переменная $wordr трактуется неправильно, если вы хотите вывести строку "He was a larger fellow". Эта проблема может быть исправлена с помощью операции кантактенации следующим образом:

$word = "large";

print "He was a " . $word . "r fellow.";

Вы можете также использовать круглые скобки, чтобы сообщить где имя начинается и заканчивается:

Использование специальной переменной $" при работе со строками. В следующем примере переменная $" = "," используется для вывода элементов массива, разделенных запятыми.

$" = ",";

@array = (1..5);

print "@array\n";

Будет выведено:

1,2,3,4,5

Вы можете использовать любой другой символ, например $" = "; " выведет точку с запятой и пробел.

Операторы

В языке Perl используются операторы, аналогичные используемым в C++. Например условные операторы имеют вид:

if (EXPR) {BLOCK}

if (EXPR){ BLOCK} else{ BLOCK}

if (EXPR) BLOCK elsif (EXPR) {BLOCK} else {BLOCK}

#Пример

$var = 1;

if ($var == 0)

{ print "\$var = 0\n"; }

elsif ($var == 1)

{ print "\$var = 1\n"; }

else

{ print "Не известное \$var\n"; }

Результат: $var = 1

В Perl используются следующие операторы циклов:

LABEL while (EXPR){ BLOCK}

LABEL while (EXPR) {BLOCK} continue{ BLOCK}

LABEL for (EXPR; EXPR; EXPR) {BLOCK}

LABEL foreach VAR (LIST) {BLOCK}

Цикл while выполняет BLOCK до тех пор пока EXPR = true. Блок после continue выполняется всегда перед вычислением выражения EXPR. Метка LABEL используется, чтобы пометить цикл, который надо прервать, и необходима при использовании внутри блока операторов next, last и redo. Если метка отсутствует, то эти операторы ссылаются на начало ближайшего цикла. Оператор next подобно оператору continue в Си переходит к началу текущего цикла.

M1:

while ($i < 6)

{ ++$i; # Увеличиваем счетчик на 1

next M1 if $i < 3; # Переходим в начало если $i < 3

++$i; # иначе увеличиваем счетчик еще раз на 1

}

continue

{ print "$i "; # Печатаем $i

}

Результат: 1 2 4 6

Оператор last - подобно оператору break в языке Си немедленно прерывает цикл. Оператор redo предписывает начать новый цикл не вычисляя EXPR и не выполняя блок continue.

Пример:

M1:

while ($i < 6)

{ ++$i; # Увеличиваем счетчик на 1

redo M1 if $i == 3; # Далее пропустить для $i = 3

++$i; # иначе увеличиваем счетчик еще раз на 1

}

continue { print "$i "; # Печатаем $i

}

Результат: 2 5 7

Оператор for полностью аналогичен оператору for в Си.

Цикл foreach имеет вид: LABEL foreach VAR (LIST) {BLOCK}

Переменной VAR присваивается поочередно каждый элемент списка LIST и выполняется блок. Вместо слова foreach можно писать просто for - это слова синонимы.

Пример:

@месяц = ("январь","февраль","март"); # Создали массив

foreach $i (@месяц)

{ print $i," "; # Печать $i

}

for $i (3,5,7)

{ print "$i "; }

Результат: январь февраль март

3 5 7

В Perl существует оператор goto.

Рассмотрим пример небольшой программы:

#!/usr/local/bin/perl

@passwords = qw (inet basic net);

print ”Enter the login: ”;

$login = ;

chomp ($login);

if ($login eq ”Root”) {

print ”Hello, Administrator! Glad to see you again!\n ”;}

else { print ”Enter password: ”;

$pass = ;

chomp ($pass);

$i = 0; $flag = ”no”;

while ($flag eq ”no”) {

if ($passwords[$i] eq $pass) {$flag = ”yes”;}

elseif ($i <2) {$i = $i + 1;}

else {print ”Incorrect password for $login, try again.\n”;

print ”Enter password: ”;

$pass = ;

chomp ($pass);

$i = 0; }

}

}

В рассматриваемом случае массив @passwords включает три элемента: inet, basic, net. Команда qw(), заключающая их в скобки, освобождает от ввода кавычек, необходимого при использовании общепринятой конструкции вида @passwords = (”inet”, ”basic”, ”net”); Оператор print служит для вывода на экран символьной информации print ”Enter the login: ”.

Затем располагается оператор ввода строки с терминала, выполняющегося в Perl с помощью конструкции . Переменная $login содержит и завершающий символ строки, например, Root будет введено как Root\n. Чтобы убрать лишний символ, требуется функция chomp, которая в качестве своего единственного параметра принимает скалярную переменную и удаляет из нее завершающий символ перехода на новую строку, если этот символ там присутствует: chomp ($login);

Наличие значения переменной $pass среди элементов массива @passwords проверяет $passwords[$i] eq $pass. Следующая ниже операция сложения $i = $i + 1; увеличивает текущее значение счетчика.

Подпрограммы

Подпрограммы необходимо определить или объявить (декларировать):

sub имя; #- декларация. Определение ниже.

sub имя блок; #- Декларация и определение.

sub имя (прототипы) {блок;} #- То же, но с параметрами.

Вызов подпрограммы:

имя(список параметров); # символ '&' можно не указывать.

имя список; # Если подпрограмма уже декларирована.

&имя; # Параметры в @_

Все параметры передаются подпрограмме как массив @_ ,который содержит адреса параметров. Соответственно $_[0] - первый параметр, $_[1] - второй и т.д. Возвращаемое значение подпрограммы - результат последнего оператора. Можно возвращать значение используя return.

Для применения переменных, доступных только внутри блока или подпрограммы, необходимо определить их с помощью функции my(список). Если переменная одна, то скобки можно опустить.

# Программа вычисления факториала.

print fact(3); # вычислить факториал 3*2*1

sub fact # Определяем подпрограмму.

{ my $m; # private переменная

$m = $_[0];

return 1 if $m <= 1;

return($m * fact($m -1)); }

Функция my позволяет указывать начальные значения переменных: my(список) = выражение; Так в приведенном примере лучше было написать: my($m) = $_[0];

В Perl реализован механизм модулей - группы подпрограмм включенных в один файл. Начало модуля определяется директивой: packages имя_модуля;. Конец модуля это конец блока или файла. Головной модуль имеет по умолчанию имя main. На имя внутри модуля можно ссылаться, добавляя '::' после имени модуля. Например: $main::var1.Для импортирования подпрограмм из других модулей используйте: use модуль qw(подпрограмма1 подпрограмма2 );

В Perl используются конструкторы и деструкторы - подпрограммы, которые выполняются в момент создания (удаления) объекта. Для модуля это подпрограммы с именами BEGIN и END.

Perl библиотеки обычно поставляется с дистрибутивом Perl и разделяются на pragma библиотеки (директивы компилятору) и стандартные библиотеки. Pragma библиотеки используют так: use имя;

В стандартный набор входят следующие pragma библиотеки:

diagnostics - включить режим расширенной диагностики; integer - использовать целочисленную арифметику; overload - hежим переопределения операторов; sigtrap - режим слежения за прерываниями; strict -режим ограниченного использования "опасных" операторов; subs - режим обязательного декларирования подпрограмм.

Рассмотрим некоторые стандартные библиотеки: AnyDBM_File - возможность работы с разными типами баз данных. Carp - предупреждения об ошибках. Config - доступ к конфигурации Perl. Cwd - получить имя текущей рабочей директории. English - использовать длинные имена встроенных переменных. Env - импортировать имена переменных окружения. ExtUtils::MakeMaker - создает файл проекта Makefile. File::Basename -синтаксический разбор спецификации файла. File::Find - Быстрый поиск файлов по директориям. File::Path –создание/удаление директорий. Net::Ping - тест доступа к хосту. Socket - определение структур и констант. Подробное описание каждой библиотеки записано в самом файле.

Программисты, работающие с Perl, создали общедоступную библиотеку модулей CPAN. Она доступна через Интернет.

Файлы

Существует три способа открытия файла: для чтения (read), дополнения (append) и записи (write). Для режима read синтаксис операции открытия файла следующий: open (HANDLE,”filename.txt”);

В круглых скобках заключен дескриптор файла HANDLE и имя файла. Для считывания информации из файла выполняется так называемая операция ромба, обозначаемая символами ():

open (HANDLE,”filename.txt”);

while (){

# цикл будет считывать информацию из файла построчно

}

Отличие синтаксиса open() для операции записи заключается в том, что перед именем файла стоит символ (>). Этот символ сообщает, что следует создать указанный в кавычках файл и записать или обновить его содержимое. Чтобы записать в него информацию, нужно обратиться к помощи оператора print:

open (HANDLE,”>filename.txt”);

print HANDLE ”Записать этот текст в файл...”;

Режим добавления (Append) синтаксически выглядит так:

open (HANDLE,”>>filename.txt”);

print HANDLE ”Дописать этот текст в файл...”;

При его описании ставится двойной знак (>>). Если указанный файл не существует, то он будет создан, в противном случае введенная информация будет добавлена в конец. Когда выполняется операция дополнения, данные можно не только записывать, но и считывать из файла.

В случае успешного выполнения функция open() возвращают значение true, иначе — false. Закрыть файл можно с помощью функции close(HANDLE). Всякий раз при открытии файла разумно использовать вместе с оператором open() оператор die. Бывает, что файл по какой-то причине нельзя правильно открыть. В подобном случае оператор die прерывает выполнение программы и выдает сообщение об ошибке при открытии файла.

open (HANDLE,”>>f.txt”)||die”Ошибка добавления в файл $!\n”;

Функция die прерывает выполнение программы. Выдается сообщение об ошибке, а также информация о том, что ее вызвало. Perl сохраняет сведения о последней системной ошибке в специальной переменной $!. В синтаксисе используется «логическое ИЛИ» (||).

Проверка существования файла.

$filename = ”filename.txt”;

if (-e $filename) {

print ”Файл $filename уже существует\n”;}

else { print ”Файл $filename не найден\n”;}

Чтобы убедиться в наличии какого-либо файла и возможности чтения из него, нужно вместо операции -e выполнить -r, а в случае требования возможности записи —w. Можно проверить один и тот же файл на доступность чтения и записи информации:

$filename = ;

chomp ($filename);# убрать символ новой строки

if (-r $filename && -w $filename) {

# файл существует, мы можем читать из него и записывать в него

}

Чтобы определить возможность чтения для целой группы файлов с одинаковым расширением, можно использовать конструкцию:

@files = ;

foreach (@files) {

print ”$_ is readable\n” if -r;

}

При большинстве подобных проверок, а их около 20, возвращается значение true или false.

При работе на Perl под управлением Windows нужно указывать полный путь к файлу (вместе с именем диска), над которым будут выполняться какие-либо действия, например:

open (HANDLE,”c:/scripts/newfile.txt”) || die ”Error opening c:/scripts/newfile.txt $!\n”;

close (HANDLE);

Common Gateway Interface

CGI представляет собой стандарт взаимодействия Web-сервера с прикладными программами, которые пользователь может выполнять на Web-сервере. Программы CGI можно писать на языках типа С++, Visual Basic, но при этом возникают проблемы их переносимости с одной серверной платформы на другую. Таких проблем с Perl нет, интерпретатор Perl существует практически на любой платформе.

Ниже будет показано, как реализовать диалог с посетителем Web-страницы. Будут рассмотрены вопросы создания программ типа гостевой книги на основе Perl. Необходимые Perl-программы можно загрузить из Internet. Вот несколько узлов: www.freescripts.com, www.scripts.ru.

Как работает CGI программа.

CGI программа всегда размещается на диске сервера до ее выполнения. Web - сервер требует размещения CGI - приложения в директорию cgi-bin, однако системный администратор может выделить вам и другой каталог. Простейший способ вызова CGI программы состоит в указании броузеру URL этой программы. Например, если вы хотите выполнить программу test.pl на локальном web - сервере, вы должны ввести URL: http://localhost/cgi-bin/test.pl. Здесь cgi-bin представляет относительный адрес, к которому может добавляться остальной путь, напрмер: /usr/local/etc/httpd/cgi-bin/test.pl или /website/cgi-shl/test.pl.

Есть и другой способ вызова CGI программы. Вы можете поставить гиперссылку, например на кнопку формы

Click here to run a CGI program

Информацию для CGI программы можно передать, добавляя ее к стандартному URL. Например Search the Document Directory

Информация о пути доступна через переменную окружения PATH_INFO.

Для поиска может быть использован знак вопроса

Search for 1993 Wines

Информация после знака вопроса доступна через переменную окружения QUERY_STRING.

Приведем пример простейшей CGI программы:

#!/usr/local/bin/perl -w

use strict;

print "Content-type: text/plain\n\n";

print "Hello, World.\n";

Файл test.pl с этой программой помещается в каталог cgi-bin web сервера. Затем задается URL вида: http://localhost/cgi-bin/test.pl

Результат: Hello, World.

При выполнении CGI программы автоматически открываются стандартные файлы STDIN - ввода информации из HTML формы, STDOUT - вывода в окно броузера, STDERR - вывода сообщений в log - файл сервера.

Первая строка вывода для CGI программы должна содержать заголовок HTTP, который сообщает броузеру клиента какой тип сообщения будет послан на STDOUT: print("Content Type: text/html\n\n");

Могут быть другие заголовки, например Location определяет какую из страниц открыть: print("Location: $nextPage\n\n");

CGI и переменные окружения

Переменные окружения доступны CGI программе через переменную %ENV. Могут использоваться следующие переменные окружения:

CONTENT_LENGTH - содержит длину записи, передаваемой скрипту через STDIN файл. Используется в методе POST.

CONTENT_TYPE - содержит тип данных, доступных через STDIN.

HTTP_ACCEPT - содержит лист MIME типов программ броузера

HTTP_USER_AGENT - тип броузера пользователя

HTTP_FROM - содержит email адрес пользователя.

PATH_TRANSTLATED - путь к скрипту

REMOTE_ADDR - числовой адрес пользователя

REMOTE_HOST - имя домена сайта из которого коннектится пользователь.

REMOTE_USER - имя пользователя.

REQUEST_METHOD - содержит метод "GET" или "POST"

SCRIPT_NAME - путь к скрипту.

SERVER_NAME имя хоста сервера.

SERVER_PORT -содержит прослушиваемый порт, стандартно 80.

SERVER_PROTOCOL имя протокола сервера.

Кодирование URL

Данные, поступившие из формы, имеют следующий вид:

=&=&=

ИмяX — имя элемента формы, определенное атрибутом NAME, а ЗначениеX — информация, введенная в соответствующее поле. Если в форме присутствует несколько элементов управления (поля ввода, ниспадающие списки, обычные списки, флажки, элементы выбора, кнопки), то пары = разделяются символом &.

Поскольку при использовании метода GET данные формы передаются как часть адреса URL, они не могут включать пробелы и другие специальные символы, применение которых в URL не допускается, а также символы, имеющие в URL другое назначение, например символ «косая черта» (/), причем последнее ограничение накладывается и при использовании метода POST. Web-браузер производит кодирование информации, представленной пользователем. Например, все символы пробелов заменяются на «+». Вместо управляющих символов ставится их шестнадцатеричный (HEX) эквивалент, вводимый после символа %. Например строка Ivan Ivankov aa@planet.net кодируется: Ivan+Ivankov+%3Caa@planet.net %3E. Символ это %3E. CGI скрипт должен раскодировать информацию.

Работа с формами

Тег использует кнопку submit, чтобы переслать данные из формы в CGI программу. Например:

Есть два способа передачи информации из формы:

и . Например:

Метод GET добавляет данные из формы в конец URL, используемого в ACTION, разделяя их знаком вопроса. Эта информация помещается в переменную окружения QUERY_STRING и используется в CGI скриптом. Метод POST используется для больших форм и посылает скрипту информацию из формы, используя файл STDIN. Размер данных которые надо прочитать, определяется с помощью переменной CONTENT_LENGTH. По умолчанию используется метод пересылки данных METHOD=”GET”. Способ передачи данных помещается в переменную REQUEST_METHOD. Рассмотрим пример:

sub getFormData {

my($buffer) = "";

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

$buffer = $ENV{'QUERY_STRING'};#чтение из буфера в методе GET

}

else {#чтение из файла в методе POST

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

}

}

В обоих случаях информация содержится в переменной $buffer .

Даннае из формы передаются в формате name=value, каждое поле разделяется амперсандом (&). Например

name=Ivan+Ivankov&age=34

Сначала разделим поля, используя & как разделитель:

name=Ivan+Ivankov

age=34

Затем разделим поля с помощью =:

Field Name: name Field Value: Ivan+Ivankov

Field Name: age Field Value: 34

В следующем примере объявим переменные, соответствующие полям формы, проинициализируем буфер, определим функцию getFormData(). Затем разделим строку с помощью функции split() и определим функцию декодирования decodeURL().

my(%frmFlds);

getFormData(\%frmFlds);

sub getFormData {

my($hashRef) = shift;

my($buffer) = "";

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

$buffer = $ENV{'QUERY_STRING'};

}

else {

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

}

foreach (split(/&/, $buffer)) {

my($key, $value) = split(/=/, $_);

$key = decodeURL($key);

$value = decodeURL($value);

%{$hashRef}->{$key} = $value;

}

}

sub decodeURL {

$_ = shift;

tr/+/ /;

s/%(..)/pack('c', hex($1))/eg;

return($_);

}

HTML-код нашей формы гостевой книги выглядит следующим образом:

ГОСТЕВАЯ КНИГА

Ваше имя:
E-Mail:
Город:
Home Page URL:

Комментарии:


Пользователь заполняет форму и подтверждает введенную им информацию нажатием кнопки submit. Затем сведения из формы передаются на сервер. К тегу необходимо добавить два параметра: METHOD, обеспечивающий посылку данных, и ACTION, в котором хранится URL к CGI-программе. Метод POST более эффективен и надежен, чем GET. Например, формы, использующие поля , позволяют пользователям вводить большое количество текста. Они должны всегда применять метод POST:

ACTION=”http://www.server.com/cgi-bin/script.cgi”

Практически во всех формах, которые приходится заполнять на тех или иных Web-узлах, присутствуют поля ввода и кнопки подтверждения. Все они создаются с помощью тега , который в отличие от и не имеет закрывающей пары. Тег , равно как и , может содержать несколько атрибутов: NAME, TYPE и VALUE. Обязательными являются первые два:

В результате отображения формы браузером первая строка образует поле для ввода информации (TYPE=«text»), а вторая — кнопку ее подтверждения (TYPE=«submit»). Можно также создать и кнопку сброса введенной информации в форме (TYPE=«reset»). Кроме TYPE используется NAME — второй важный параметр. Он придает каждому объекту формы свое уникальное имя. А в качестве необязательного атрибута тег может содержать VALUE. В него записывается значение, отображаемое в соответствующих элементах формы при ее загрузке. Например, использование VALUE=«@» приведет к тому, что при загрузке формы в браузер поле ввода адреса электронной почты будет содержать символ @.

Заполним форму, исходный текст которой приводился и, нажав кнопку PostIt, подтвердим ее!

Программа обработки данных из формы и вывода их в браузер

#!/usr/local/bin/perl

&GetFormInput;

$Name=$field{‘name’};

$Email=$field{‘email’};

$City=$field{‘city’};

$Url=$field{‘url’};

$Comments=$field{‘comments’};

print ”Content-type:text/html\n\n”;

&Title;

print ”Name: $Name
\n

Email:

$Email
\n

City: $City
\n

Url:

$Url
\n

Comments: $Comments
\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;

}

sub Title {

print ”Simple GuestBook

\n”;

return 1;

}

В результате произойдет запуск серверной программы для обработки этой формы и вывода данных в виде отдельной HTML-странички. В форме использовался метод GET, так как в строке ввода адреса вместе с названием самой CGI-программы присутствуют также закодированные данные.

Если использовать метод POST, то в строке адреса отобразится только название самой CGI-программы. Алгоритм работы программы очень прост: вызывается подпрограмма &GetFormInput, декодирующая данные из формы, которые затем записываются в соответствующие переменные. Далее с помощью строки print «Content-type:text/html\ n\n» объявляется MIME-тип вывода информации (в данном случае — в виде HTML-страницы), потом запускается подпрограмма &Title для вывода заголовка «Simple Guestbook» и в конце выводятся декодированные данные в Web-браузер в виде HTML-страницы.

Гостевая книга должна сохранять введенные пользователем данные в каком-либо файле для дальнейшего их отображения и использования при новом посещении страницы.

Процесс декодирования данных формы практически во всех CGI-программах одинаков. Поэтому, чтобы не повторять его от программы к программе, создаются библиотеки подпрограмм. На сегодняшний день самые популярные из них для Perl — CGI-LIB.PL и CGI.PM. Благодаря этим программам можно сократить размер Perl-программы. Возможностями CGI-LIB.PL воспользуемся ниже.

Для объявления библиотеки необходимо в начале программы написать: require ”../cgi-lib.pl”;

В кавычках указан физический путь к библиотеке. Если требуется, можно организовать и свою библиотеку с набором часто используемых собственных подпрограмм:

require ”../mylib.pl”;

Объявив эту библиотеку в начале программы гостевой книги, можно убрать из текста подпрограмму декодирования данных. Теперь для обработки закодированных данных нужно просто вызвать из нее соответствующую подпрограмму. Это действие практически не отличается от вызова обычной внутренней подпрограммы: &Parse_Data;

Из-за того что используется библиотечная подпрограмма (а она, естественно, отличается названиями переменных), в месте присваивания данных переменным нужно $field{‘ ‘} заменить на $CGI{‘ ‘}. А после внесения всех необходимых изменений в текст программы гостевой книги следует реализовать механизм сохранения пользовательской информации в текстовую базу данных

# Создание текстовой БД записей посетителей

#!/usr/local/bin/perl

require 'cgi_lib.pl';

&Parse_Data;

$Name=$CGI{'name'};

$Email=$CGI{'email'};

$City=$CGI{'city'};

$Url=$CGI{'url'};

@Comments=$CGI{'comments'};

# Убираем символы конца строки из переменной окна прокрутки

$c=0;

foreach (@Comments) {

$Comments[$c] =~ s/\n/ /g;

chomp($Comments[$c]);

$q=$Comments[$c]+$Desc[$c];

$q = ~ s/\n/ /g;

$c++;

}

$file="guestbook";

$dbase="../";

open (F, "+>>$dbase/$file") || die "Error of adding a record

$!\n";

print F join ("::","$Name", "$Email", "$City", "$Url",

"@Comments"),"\n";

$i=1;

foreach (@F) {

print F $_;

$i++;

}

close (F);

print "Content-type:text/html\n\n";

&Title;

print "Name: $Name
\n

Email: $Email
\n

City: $City
\n

Url: $Url
\n

Comments: $Comments
\n";

CGI-программа обрабатывает введенные данные и записывает их в файл. Вместо обычного открытия файла для записи используется режим добавления записей (Append), чтобы не была уничтожена записанная ранее информация.

Web -сервер

Что делает web – сервер? Web сервер Apache просто забирает пакеты идущие по адресу 127.0.0.1 или "http://localhost". Затем их обрабатывает и отсылает ответ клиенту. Клиент ожидает ответ на запрос (Request).

Apache будет установлен в любую директорию какую вы укажете. Можете создать файл конфигурации config.conf, а можете, не удаляя старой конфигурации, воспользоваться новой, указав в коммандной строке соответственно комманду -f "path", где path это полный путь к файлу новой конфигурации *.cfg. Вам будет предложено установить Apache Server в какую-либо директорию. В строке "Install to" введите полный путь для установки, к примеру z:\home\web_server. В результате этого будут созданы папка Apache и файл MakeConf.exe. Запустите MakeConf.exe из директории, где он был создан, и укажите ту же папку что и при инсталляции, только с маленькой оговоркой: для правильного создания файла конфигурации путь надо будет прописывать с правым слэшем: "z:/home/web_server".

Для запуска Apache сервера используйте файл start_apache.cmd, для остановки stop.cmd.Все ошибки, которые возникнут в процессе работы с сервером будут занесены в файлы error.log и access.log в директории logs.

Приложение 4.

БАЗЫ ДАННЫХ И ЯЗЫК SQL

Каждая область человеческой деятельности нуждается в хранении и обработке сопутствующей информации. Например, библиотека хранит сведения о книжных фондах и параллельно ведет списки читателей, бухгалтерия оперирует счетами и производит различные операции над ними. Склад ведет учет наличия товаров и отслеживает их движение.

Под базой данных (БД) понимается некий организованный набор информации. В качестве примера простейшей БД можно привести список товаров, каждый из которых обладает набором стандартных характеристик (наименование, единица измерения, количество, цена и т.д.):

Наименование Ед. Изм. Цена Кол-во
Кирпич штука
Краска литр
Шифер лист
Гвоздь штука
Кабель метр

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

Базовые функции СУБД:

Реляционные СУБД


7828041255337390.html
7828102811760702.html
    PR.RU™