Рассылка закрыта
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
← Ноябрь 2000 → | ||||||
1
|
2
|
3
|
4
|
5
|
||
---|---|---|---|---|---|---|
6
|
7
|
8
|
9
|
11
|
12
|
|
13
|
14
|
15
|
16
|
17
|
18
|
19
|
20
|
21
|
23
|
24
|
25
|
26
|
|
27
|
28
|
29
|
30
|
Статистика
за неделю
Программирование скриптов на Perl'e (Выпуск №7)
Программирование скриптов на Perl'e (выпуск 7).
Здравствуйте дорогие мои подписчики.
Сегодня в выпуске:
- Несколько слов перед началом
- Perl для начинающих - Операторы Perl'а
- CGI-программирование - Библиотека cgi-lib.pl
- Внимание - конкурс
- Наши друзья
- О рассылке
- Обращение к рекламодателям
Несколько слов перед началом
Ура!!! Количество подписчиков на рассылку превысило 5000 человек. Как мне кажется, непрерывное увеличение количества подписчиков, указывает на то, что эта рассылка все-таки нужна некоторым людям, и я постараюсь не обмануть Ваши надежды, дорогие мои читатели.
Извините, что задержался с выпуском этого номера. Надеюсь, что Ваше ожидание не было слишком долгим, и что оно компенсируется объемом этого выпуска.
Итак, начнем, пожалуй. Сегодняшние темы:
Perl для начинающих - Операторы Perl'а
В то время как типы данных и переменных языка Perl значительно отличаются от соответствующих типов языка С, операторы и выражения Perl'а должны вам показаться гораздо более знакомыми. Все операторы С присутствуют в языке Perl, за небольшим исключением. Кроме того, в языке Perl реализовано много новых операторов для использования в таких операциях как сравнение и обработка строк.
Арифметические операторы
+ - сложение - - вычитание или изменение знака * - умножение / - деление (только для чисел с плавающей запятой) % - взятие по модулю (только для целочисленных значений) Рассмотрим примеры арифметических операций языка Perl: $x=2.5; $y=3; print ($x+2*$y); # выведет 8.5 print (7/$y); # выведет 2.3333333 print int (7/$y); # выведет 2 print (7%$y); # выведет 1 print (7.5%$y); # выведет 1Примечание: В Perl'е оператор деления всегда имеет результатом число с плавающей точкой, а результатом взятия одного числа по модулю другого является целое число и, причем предварительно оба операнда преобразуются к целому типу.
Рассмотрим следующую операцию взятия по модулю: print (7.9%3.6); # выведет 1 то же (7%3)=1 Perl также поддерживает операторы инкремента и декремента: -- - декремент в префиксной или постфиксной форме ++ - инкремент в префиксной или постфиксной формеЕсли оператор стоит перед переменной, то значение переменной изменяется на 1 и полученной значение используется. Если после переменной, то ее величина изменяется после применения.
Рассмотрим примеры операций инкремента и декремента: $x=4; ++$x; print $x; # выведет 5 $y=$x--; # уменьшит x после присвоения y значения x print "$y $x" # выведет 5 4Употребление инкремента к строковым переменным в Perl'е имеет одну особенность. Каждый символ остается в своем классе (большие, малые, цифры) и учитывается перенос предыдущего символа. Таким образом, строковые переменные с цифрами работают как числовые переменные.
Пример: print ++($i="09"); # Результат "10" print ++($i="a9"); # "b0" print ++($i="az"); # "ba" print ++($i="aZ"); # "bA"Наконец, Perl обеспечивает арифметический оператор для возведения в степень (**). Рассмотрим следующие примеры использования операции возведения в степень:
$x=2**3; # результат 8 $x=2**0.5; # квадратный корень из 2 $x=-2**-3; # 1/(-2 в кубе), результат -1/8 (-0.125)
Побитовые операторы
| - побитовое ИЛИ & - побитовое И ^ - побитовое исключающее ИЛИ ~ - побитовая инверсия << - сдвиг влево >> - сдвиг вправо Рассмотрим следующие примеры побитовых операций: $x=5; # 101 в двоичном $y=3; # 011 в двоичном print $x|$y; # 7 (111) print $x&$y; # 1 (001) print $x^$y # 6 (110) print $x&~1; # 4 (100) print $x<<2 # 20 (10100) print $x>>1 # 2 (10)Так же как и в С, поведение операторов сдвига вправо зависит от реализации языка в случае, если операнд является отрицательным.
Операторы сравнения
Операторы сравнения: Число Строка Значение ------------------------------------------------------- == eq равно != nе не равно > gt больше чем < it меньше чем >= gе больше или равно <= lе меньше или равно <=> cmp не равно (результат со знаком)Результатом операции сравнения является единица, если сравнение истинно и нуль в противном случае. Однако последняя операция (<=> или cmp) может возвращать значения -1, 0 или 1 в зависимости от того, является ли значение первого операнда меньше, чем второго, равным ему или большим.
Примечание: Оператор cmp языка Perl ведет себя, аналогично функции strcmp() языка С.
Рассмотрим следующий пример сравнения: $x=5; # x равно 5 print ($x<4); # если false, то выведет 0
Логические операторы
Логические операторы Perl'а включают следующие:
&& - логическое И (если левое выражение возвращает false,
правое не выполняется)
|| - логическое ИЛИ (если левое выражение возвращает true,
правое не выполняется)
Perl всегда обрабатывает логические выражения слева направо. Кроме того, Perl всегда прекращает оценку, если уже выполненной оценки достаточно, чтобы определить значение результата. В дополнение к общим логическим операторам Perl поддерживает следующие дополнительные логические операторы:
! - логическое отрицание ?: - условная операция , - последовательное выполнениеОператор логического отрицания (!) заменяет значение булевой величины на противоположную. Так же как и в С, в Perl'е условный оператор (?:) использует три операнда. Выражение, использующее условный оператор, имеет следующую форму:
Condition ? true-result : false-resultАналогично, следующее выражение использует условный оператор для того, чтобы предоставить администратору полный доступ, а всем остальным ограниченный:
$access=($user eq 'root' ? 'Full' : 'Limited');Оператор последовательного выполнения (,), также известный как оператор "запятая", не является вполне логическим оператором, поскольку он не анализирует истинность своих операндов. Perl выполняет операнды оператора последовательного выполнения слева направо и возвращает значение самого правого операнда.
Следующий пример иллюстрирует использование оператора запятая в цикле for:
for ($i=0, $j=10; $i<10; $i++, $j--) { print $i,' ',$j,"\n"; } Результат: 0 10 1 9 2 8 3 7 4 6 5 5 6 4 7 3 8 2 9 1
Строковые операторы
. - конкатенация строк х - репликация =~ - сопоставление переменной с образцом !~ - то же, что и предыдущее, но с дополненным отрицанием результата Первые два оператора легко иллюстрируются примером: print 'b' . 'an' x 2 . 'a'; # выведет 'banana'Как показано, это выражение использует конкатенацию строк и оператор репликации для того, чтобы напечатать строку "banana".
Два последних оператора используются для проверки того, включает ли строковый операнд заданный образец. Следующий пример иллюстрирует их использование:
$var='banana'; print ($var=~/ana/) ? TRUE : FALSE;В этом случае оператор проверки вхождения в строку образца (=~) использовался для проверки того, входит ли образец ana в переменную $var. В данном случае выражение принимает значение "истинно".
Операторы присваивания
= += -= *= /= %= |= &= ^= ~= <<= >>= **= .= x=Когда вы работаете со списками в языке Perl, оператор присваивания не обязательно относится ко всему списку. Скрипт может присваивать значения отдельным элементам списка, как показано ниже:
@items[2, 4, 7]=(100, 200, 300);В этом случае оператор присваивает значение трем элементам списка. Аналогичным образом следующее выражение распаковывает элементы списка, присваивая значения двух первых элементов двум скалярным переменным, а остаток массива - списочной переменной:
($arg1, $arg2, @rest)=@ARGV;
Операуии для работы со списками
, - конструктор списков .. - оператор области х - оператор репликацииВы уже использовали конструктор списков для инициализации массивов и создания списка переменных. Оператор области возвращает в качестве значения последовательность целых чисел, которая начинается от левого операнда и продолжается до правого операнда включительно. В скриптах часто используют оператор области совместно с конструктором списков для создания списков. Например, следующее выражение использует оператор области для того, чтобы создать список под именем @digits, который содержит числа от нуля до девяти:
@digits = 0..9; # список (1, 2, 3, 4, 5, 6, 7, 8, 9)Аналогичным образом, это выражение может использовать оператор области для создания области изменений индексов массива. Предположим, что список @days содержит дни недели (начиная с воскресенья). В следующем выражении списку @weekdays присваиваются значения, начиная от понедельника до пятницы:
@weekend = @days[1..5];Наконец, следующее выражение использует два оператора области для создания списка шестнадцатеричных цифр:
@hex_digits = (0..9, a..f);Оператор репликации просто создает копии данного операнда указанное число раз.
Приоритеты выполнения операторов
++ -- ! ~ \ унарные + и - ** =~ !~ * / % х + - . << >> -d -е -s -w (и другие файловые операторы) < > <= >= It gt le ge == != <=> eq ne cmp & | ^ && || .. ?: = += -= *= и т. д. , => not and or xorВ своем скрипте вы можете изменять последовательность выполнения операторов с помощью скобок.
На этом на сегодня все с операторами Perl'а.
CGI-программирование - Библиотека cgi-lib.pl
После того как у меня в рассылке появился раздел, посвященный CGI-программированию, я получил письмо, опубликованное в № 5 данной рассылки. Как Вы помните (если нет - то напомню) в нем мне предлагалось использовать модуль CGI для упрощения работы.
Сегодня я представляю Вашему вниманию перевод части книги Юджина Эрика Кима (Eugene Eric Kim) "Руководство CGI Разработчика" (CGI Developer's Guide), посвященной библиотеке cgi-lib.pl.
Руководство по использованию cgi-lib.pl.
СОДЕРЖАНИЕ
|
Библиотека cgi-lib.pl Стива Бреннера была одним из первых общедоступных и широко используемых библиотек CGI-программирования. cgi-lib.pl очень упрощает CGI-программирование в Perl'е, обеспечивая процедуры разбора запросов и другие полезные CGI-процедуры. Эта библиотека написана для Perl 4, хотя будет работать и с Perl 5.
Первичная функция cgi-lib.pl это разбор ввода формы. Она разбирает ввод формы и размещает данные в хэше, ассоциирую значения полей с их именами. Эта библиотека развивалась, начиная с ее первого выпуска и может работать с регулярным декодированным вводом формы (application/x-www-form-urlencoded - данные, которые посланы как аргументы непосредственно в URL) и многоблочным декодированным вводом формы, используемым для недавно предложенной HTML загрузки файла (multipart/form-data - данные, которые посланы как стандартный ввод подобно многоблочным приложениям электронной почты).
В этом приложение показан очень простой пример того, как использовать cgi-lib.pl и описываются все доступная процедуры. Полный исходный текст библиотеки cgi-lib.pl приведен в конце.
Линкольн Стейн написал очень хорошую библиотеку для Perl 5 называемую CGI.pm, которая включает поддержку разбора ввода формы, вывод HTML-форм и внутреннюю отладку. Если Вы знаете Perl 5 или планируете изучать его, то я рекомендую Вам ее. Она доступна на http://www-genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html
Чтобы использовать cgi-lib.pl, Вы должны разместить ее или в том же самом каталоге, что и Ваши Perl-скрипты или в глобальном каталоге Perl-библиотек (обычно это /usr/lib/perl на UNIX машинах). На UNIX машинах удостоверьтесь, что cgi-lib.pl доступна для чтения всем.
Использование cgi-lib.pl требует двух шагов: включение библиотеки в скрипт и запроса функций. Минимальная CGI программа, использующая cgi-lib.pl:
#!/usr/bin/perl if (&ReadParse(*input)) { print &PrintHeader,&HtmlTop("Form Results"); print &PrintVariables,&HtmlBot; } else { print &PrintHeader,&HtmlTop("Entry Form"); print <<EOM; <form method=POST> <p> Name: <input name="name"><br> Age: <input name="age"> <p> <input type=submit> </form> EOM print &HtmlBot; }Эта программа делает следующее:
Главная процедура - &ReadParse, которая берет каждую пару имя/значение формы и помещает в хэш %input. Массив сортирован по имени, так $input{'name'} эквивалентно 'value'.
&PrintHeader, &HtmlTop, &PrintVariables и &HtmlBot - все HTML-функции вывода,
описанные более подробно дальше.
Процедуры и Переменные
В этом разделе я описал и определил функции и переменные, которые доступны в библиотеке cgi-lib.pl.
&ReadParse
Если имя имеет больше чем одно ассоциированное значение, то значения отделяются нулевым символом. Вы можете использовать функцию &SplitParam, чтобы разделить значения $varname{name}.
Если Вы хотите использовать &ReadParse для сохранения загружаемых файлов, используя HTML загрузку файла,
Вы должны изменить значение переменной $cgi-lib'writefiles в cgi-lib.pl с 0 на 1.
&PrintHeader
Эта функция вызывается так: print &PrintHeader;
&HtmlTop
print &HtmlTop("Hello, World!");
выведет следующее:
<html><head> <title>Hello, World!</title> </head> <body> <h1>Hello, World!</h1>
&HtmlBot
</body></html>
&SplitParam
<form method=POST> Street 1: <input name="street"><br> Street 2: <input name="street"><br> <input type=submit> </form>и разбираете ее ввод, используя:
&ReadParse(*input);
то получаете следующие значения $input{'street'}:
value1\0value2
Чтобы разделить эти значения, Вы можете cделать следующее:
@streets=&SplitParam($input{'street'});
что возвратило бы список:
(value1, value2)
&MethGet
&MethPost
&MyBaseUrl
http://hcs.harvard.edu/cgi-bin/finger?eekim
то &MyBaseUrl возвратит следующее:
http://hcs.harvard.edu:80/cgi-bin/finger
&MyFullUrl
http://hcs.harvard.edu/cgi-bin/counter.cgi/~eekim?file.html
то &MyFullUrl возвратит следующее:
http://hcs.harvard.edu:80/cgi-bin/counter.cgi/~eekim?file.html
&CgiError
Error: script $name encountered fatal error
(Ошибка: скрипт $name столкнулся с фатальной ошибкой)
где $name - значение &MyFullUrl. Например:
&CgiError("Ошибка", "Невозможно открытый файл", "Пожалуйста, сообщите об этом администратору сервера" );возвращает такое HTML сообщение:
<html> <head> <title>Ошибка</title> </head> <body> <h1>Ошибка</h1> <p>Невозможно открыть файл</p> <p>Пожалуйста, сообщите об этом администратору сервера</p> </body> </html>
&CgiDie
&PrintVariables
<dl compact> <dt><b>name</b> <dd><i>eugene</i>:<br> <dt><b>age</b> <dd><i>21</i>:<br> </dl>
&PrintEnv
Исходный Код Библиотеки
# Perl Routines to Manipulate CGI input # S.E.Brenner@bioc.cam.ac.uk # $Id: cgi-lib.pl,v 2.8 1996/03/30 01:36:33 brenner Rel $ # # Copyright (c) 1996 Steven E. Brenner # Unpublished work. # Permission granted to use and modify this library so long as the # copyright above is maintained, modifications are documented, and # credit is given for any use of the library. # # Thanks are due to many people for reporting bugs and suggestions # especially Meng Weng Wong, Maki Watanabe, Bo Frese Rasmussen, # Andrew Dalke, Mark-Jason Dominus, Dave Dittrich, Jason Mathews # For more information, see: # http://www.bio.cam.ac.uk/cgi-lib/ ($cgi_lib'version = '$Revision: 2.8 $') =~ s/[^.\d]//g; # Parameters affecting cgi-lib behavior # User-configurable parameters affecting file upload. $cgi_lib'maxdata = 131072; # maximum bytes to accept via POST-2^17 $cgi_lib'writefiles = 0; # directory to which to write files, or # 0 if files should not be written $cgi_lib'filepre = "cgi-lib"; # Prefix of file names, # in directory above # Do not change the following parameters # unless you have special reasons $cgi_lib'bufsize = 8192; # default buffer size # when reading multipart $cgi_lib'maxbound = 100; # maximum boundary length # to be encounterd $cgi_lib'headerout = 0; # indicates whether the header # has been printed # ReadParse # Reads in GET or POST data, converts it to unescaped text, and # puts key/value pairs in %in, using "\0" to separate multiple # selections # Returns >0 if there was input, 0 if there was no input # undef indicates some failure. # Now that cgi scripts can be put in the normal file space, # it is useful to combine both the form and the script in one # place. If no parameters are given (i.e., ReadParse returns # FALSE), then a form could be output. # If a reference to a hash is given, then the data will be stored # in that hash, but the data from $in and @in will become # inaccessable. # If a variable-glob (e.g., *cgi_input) is the first parameter to # ReadParse, information is stored there, rather than in $in, @in, # and %in. Second, third, and fourth parameters fill associative # arrays analagous to %in with data relevant to file uploads. # If no method is given, the script will process both command-line # arguments of the form: name=value and any text that is in # $ENV{'QUERY_STRING'} This is intended to aid debugging and may # be changed in future releases. sub ReadParse { local (*in) = shift if @_; # CGI input local (*incfn, # Client's filename (may not be provided) *inct, # Client's content-type (may not be provided) *insfn) = @_; # Server's filename (for spooled files) local ($len, $type, $meth, $errflag, $cmdflag, $perlwarn); # Disable warnings as this code deliberately uses local and # environment variables which are preset to undef (i.e., not # explicitly initialized) $perlwarn = $^W; $^W = 0; # Get several useful env variables $type = $ENV{'CONTENT_TYPE'}; $len = $ENV{'CONTENT_LENGTH'}; $meth = $ENV{'REQUEST_METHOD'}; if ($len > $cgi_lib'maxdata) { &CgiDie("cgi-lib.pl: Request to receive too much data: $len bytes\n"); } if (!defined $meth || $meth eq '' || $meth eq 'GET' || $type eq 'application/x-www-form-urlencoded') { local ($key, $val, $i); # Read in text if (!defined $meth || $meth eq '') { $in = $ENV{'QUERY_STRING'}; $cmdflag = 1; # also use command-line options } elsif($meth eq 'GET' || $meth eq 'HEAD') { $in = $ENV{'QUERY_STRING'}; } elsif ($meth eq 'POST') { $errflag = (read(STDIN, $in, $len) != $len); } else { &CgiDie("cgi-lib.pl: Unknown request method: $meth\n"); } @in = split(/[&;]/,$in); push(@in, @ARGV) if $cmdflag; # add command-line parameters foreach $i (0 .. $#in) { $in[$i] =~ s/\+/ /g; # Convert plus to space ($key, $val) = split(/=/,$in[$i],2); # splits = $key =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge; $val =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge; # Associate key and value # \0 is the multiple separator $in{$key} .= "\0" if (defined($in{$key})); $in{$key} .= $val; } } elsif ($ENV{'CONTENT_TYPE'} =~ m#^multipart/form-data#) { # for efficiency, compile multipart code only if needed $errflag = !(eval <<'END_MULTIPART'); local ($buf, $boundary, $head, @heads, $cd, $ct, $fname, $ctype, $blen); local ($bpos, $lpos, $left, $amt, $fn, $ser); local ($bufsize, $maxbound, $writefiles) = ($cgi_lib'bufsize, $cgi_lib'maxbound, $cgi_lib'writefiles); # The following lines exist solely to eliminate # spurious warning messages $buf = ''; # find boundary ($boundary) = $type =~ /boundary="([^"]+)"/; #"; ($boundary) = $type =~ /boundary=(\S+)/ unless $boundary; &CgiDie ("Boundary not provided") unless $boundary; $boundary = "--" . $boundary; $blen = length ($boundary); if ($ENV{'REQUEST_METHOD'} ne 'POST') { &CgiDie("Invalid request method for multipart/form-data: $meth\n"); } if ($writefiles) { local($me); stat ($writefiles); $writefiles = "/tmp" unless -d _ && -r _ && -w _; # ($me) = $0 =~ m#([^/]*)$#; $writefiles .= "/$cgi_lib'filepre"; } # read in the data and split into parts: # put headers in @in and data in %in # General algorithm: # There are two dividers: the border and the '\r\n\r\n' between # header and body. Iterate between searching for these # Retain a buffer of size(bufsize+maxbound); the latter part is # to ensure that dividers don't get lost by wrapping between two # bufs. Look for a divider in the current batch. If not found, # then save all of bufsize, move the maxbound extra buffer to the # front of the buffer, and read in a new bufsize bytes. If a # divider is found, save everything up to the divider. Then empty # the buffer of everything up to the end of the divider. Refill # buffer to bufsize+maxbound Note slightly odd organization. Code # before BODY: really goes with code following HEAD:, but is put # first to 'pre-fill' buffers. BODY: is placed before HEAD: # because we first need to discard any 'preface,' which would be # analagous to a body without a preceeding head. $left = $len; PART: # find each part of the multi-part while reading data while (1) { last PART if $errflag; $amt = ($left > $bufsize+$maxbound-length($buf) ? $bufsize+$maxbound-length($buf): $left); $errflag = (read(STDIN, $buf, $amt, length($buf)) != $amt); $left -= $amt; $in{$name} .= "\0" if defined $in{$name}; $in{$name} .= $fn if $fn; $name=~/([-\w]+)/; # This allows $insfn{$name} # to be untainted if (defined $1) { $insfn{$1} .= "\0" if defined $insfn{$1}; $insfn{$1} .= $fn if $fn; } BODY: while (($bpos = index($buf, $boundary)) == -1) { if ($name) # if no $name, then it's the discard { if ($fn) { print FILE substr($buf, 0, $bufsize); } else { $in{$name} .= substr($buf, 0, $bufsize); } } $buf = substr($buf, $bufsize); $amt = ($left > $bufsize ? $bufsize : $left); $errflag = (read(STDIN, $buf, $amt, $maxbound) != $amt); $left -= $amt; } if (defined $name) # if no $name, then it's the discard { if ($fn) { print FILE substr($buf, 0, $bpos-2); } else # kill last \r\n { $in {$name} .= substr($buf, 0, $bpos-2); } } close (FILE); last PART if substr($buf, $bpos + $blen, 4) eq "--\r\n"; substr($buf, 0, $bpos+$blen+2) = ''; $amt = ($left > $bufsize+$maxbound-length($buf) ? $bufsize+$maxbound-length($buf) : $left); $errflag = (read(STDIN, $buf, $amt, length($buf)) != $amt); $left -= $amt; undef $head; undef $fn; HEAD: while (($lpos = index($buf, "\r\n\r\n")) == -1) { $head .= substr($buf, 0, $bufsize); $buf = substr($buf, $bufsize); $amt = ($left > $bufsize ? $bufsize : $left); $errflag = (read(STDIN, $buf, $amt, $maxbound) != $amt); $left -= $amt; } $head .= substr($buf, 0, $lpos+2); push (@in, $head); @heads = split("\r\n", $head); ($cd) = grep (/^\s*Content-Disposition:/i, @heads); ($ct) = grep (/^\s*Content-Type:/i, @heads); ($name) = $cd =~ /\bname="([^"]+)"/i; #"; ($name) = $cd =~ /\bname=([^\s:;]+)/i unless defined $name; # filename can be null-str ($fname) = $cd =~ /\bfilename="([^"]*)"/i; #"; ($fname) = $cd =~ /\bfilename=([^\s:;]+)/i unless defined $fname; $incfn{$name} .= (defined $in{$name} ? "\0" : "") . $fname; ($ctype) = $ct =~ /^\s*Content-type:\s*"([^"]+)"/i; #"; ($ctype) = $ct =~ /^\s*Content-Type:\s*([^\s:;]+)/i unless defined $ctype; $inct{$name} .= (defined $in{$name} ? "\0" : "") . $ctype; if ($writefiles && defined $fname) { $ser++; $fn = $writefiles . ".$$.$ser"; open (FILE, ">$fn") || &CgiDie("Couldn't open $fn\n"); } substr($buf, 0, $lpos+4) = ''; undef $fname; undef $ctype; } 1; END_MULTIPART &CgiDie($@) if $errflag; } else { &CgiDie("cgi-lib.pl: Unknown Content-type: $ENV{'CONTENT_TYPE'}\n"); } $^W = $perlwarn; return ($errflag ? undef : scalar(@in)); } # PrintHeader # Returns the magic line which tells WWW that we're an HTML # document sub PrintHeader { return "Content-type: text/html\n\n"; } # HtmlTop # Returns the <head> of a document and the beginning of the body # with the title and a body <h1> header as specified by the # parameter sub HtmlTop { local ($title) = @_; return <<END_OF_TEXT; <html> <head> <title>$title</title> </head> <body> <h1>$title</h1> END_OF_TEXT } # HtmlBot # Returns the </body>, </html> codes for the bottom of every HTML # page sub HtmlBot { return "</body>\n</html>\n"; } # SplitParam # Splits a multi-valued parameter into a list of the constituent # parameters sub SplitParam { local ($param) = @_; local (@params) = split ("\0", $param); return (wantarray ? @params : $params[0]); } # MethGet # Return true if this cgi call was using the GET request, false # otherwise sub MethGet { return (defined $ENV{'REQUEST_METHOD'} && $ENV{'REQUEST_METHOD'} eq "GET"); } # MethPost # Return true if this cgi call was using the POST request, false # otherwise sub MethPost { return (defined $ENV{'REQUEST_METHOD'} && $ENV{'REQUEST_METHOD'} eq "POST"); } # MyBaseUrl # Returns the base URL to the script (i.e., no extra path or query # string) sub MyBaseUrl { local ($ret, $perlwarn); $perlwarn = $^W; $^W = 0; $ret = 'http://' . $ENV{'SERVER_NAME'} . ($ENV{'SERVER_PORT'} != 80 ? ":$ENV{'SERVER_PORT'}" : '') . $ENV{'SCRIPT_NAME'}; $^W = $perlwarn; return $ret; } # MyFullUrl # Returns the full URL to the script (i.e., with extra path or # query string) sub MyFullUrl { local ($ret, $perlwarn); $perlwarn = $^W; $^W = 0; $ret='http://'. $ENV{'SERVER_NAME'}. ($ENV{'SERVER_PORT'} != 80 ? ":$ENV{'SERVER_PORT'}" : ''). $ENV{'SCRIPT_NAME'}. $ENV{'PATH_INFO'}. (length ($ENV{'QUERY_STRING'}) ? "?$ENV{'QUERY_STRING'}" : ''); $^W = $perlwarn; return $ret; } # MyURL # Returns the base URL to the script (i.e., no extra path or query # string) # This is obsolete and will be removed in later versions sub MyURL { return &MyBaseUrl; } # CgiError # Prints out an error message which which containes appropriate # headers, markup, etcetera. # Parameters: # If no parameters, gives a generic error message # Otherwise, the first parameter will be the title and the rest # will be given as different paragraphs of the body sub CgiError { local (@msg) = @_; local ($i,$name); if (!@msg) { $name = &MyFullUrl; @msg = ("Error: script $name encountered fatal error\n"); } if (!$cgi_lib'headerout) { print &PrintHeader; print "<html>\n<head>\n<title>$msg[0]</title>\n</head>\n<body>\n"; } print "<h1>$msg[0]</h1>\n"; foreach $i (1 .. $#msg) { print "<p>$msg[$i]</p>\n"; } $cgi_lib'headerout++; } # CgiDie # Identical to CgiError, but also quits with the passed error # message. sub CgiDie { local (@msg) = @_; &CgiError (@msg); die @msg; } # PrintVariables # Nicely formats variables. Three calling options: # A non-null associative array - prints the items in that array # A type-glob - prints the items in the associated assoc array # nothing - defaults to use %in # Typical use: &PrintVariables() sub PrintVariables { local (*in) = @_ if @_ == 1; local (%in) = @_ if @_ > 1; local ($out, $key, $output); $output = "\n<dl compact>\n"; foreach $key (sort keys(%in)) { foreach (split("\0", $in{$key})) { ($out = $_) =~ s/\n/<br>\n/g; $output .= "<dt><b>$key</b>\n <dd>:<i>$out</i>:<br>\n"; } } $output .= "</dl>\n"; return $output; } # PrintEnv # Nicely formats all environment variables and returns HTML string sub PrintEnv { &PrintVariables(*ENV); } # The following lines exist only to avoid warning messages $cgi_lib'writefiles = $cgi_lib'writefiles; $cgi_lib'bufsize = $cgi_lib'bufsize ; $cgi_lib'maxbound = $cgi_lib'maxbound; $cgi_lib'version = $cgi_lib'version; 1; #return trueЯ надеюсь, что это описание поможет Вам в нелегком деле написания CGI-скриптов, хотя я предпочитаю писать код сам.
Внимание - конкурс
Сегодня я предлагаю Вашему вниманию конкурс на лучший скрипт счетчика посещений.
Условия конкурса следующие:
Огромная просьба не присылать счетчики, взятые из коллекций готовых скриптов.
Лучшая работа, с указанием авторства, будет опубликована в рассылке и на ее примере разобрано
построение счетчиков посещений.
Наши друзья
Дорогие подписчики! Если Вы еще не заглядывали на сайт наших друзей "InfoCity - виртуальный город компьютерной документации" (http://www.infocity.kiev.ua), то Вам обязательно стоит там побывать.
Очень грамотно организованный сервер компьютерной документации. Не пугайтесь титульного листа и ныряйте внутрь. Количество книжек в электронном виде потрясает и радует.
Здесь Вы можете сразу и подписаться на регулярные новости библиотеки. Для этого просто вставьте Ваш e-mail в соответствующее поле, ну и конечно же не забудьте нажать на кнопочку "OK", и все. :-))
Адрес рассылки "Новости компьютерной библиотеки InfoCity" в Каталоге subscribe.ru: http://subscribe.ru/catalog/comp.paper.infocity/
Архив рассылки "Новости компьютерной библиотеки InfoCity" находится на subscribe.ru по адресу: http://subscribe.ru/archive/comp.paper.infocity/
Предлагаю Вашему вниманию еще одного из наших друзей, который имеет непосредственное отношение к тематике этой рассылки, сайт посвященный скриптам: "WebScript.Ru - каталог скриптов". Его адрес в Internet'е - http://webscript.ru/ и там Вы найдете множество готовых скриптов как на Perl'e, так и на РНР.
Кроме того, предлагаю Вашему вниманию рассылку, посвященную новостям этого сайта, новым поступлениям скриптов и темам на форуме, а также новостям из мира Perl'а и PHP - "Новости сайта "Каталог скриптов (Perl & PHP)"".
Подписаться на нее можно здесь:
Адрес рассылки "Новости сайта "Каталог скриптов (Perl & PHP)"" в Каталоге subscribe.ru: http://subscribe.ru/catalog/inet.webbuild.webscript/
Архив рассылки "Новости сайта "Каталог скриптов (Perl & PHP)"" находится на subscribe.ru по адресу: http://subscribe.ru/archive/inet.webbuild.webscript/
Еще один наш друг - сайт "CGI-REVIEW" (http://cgizone.org), который также посвящен CGI-скриптам.
Обзор CGI-скриптов (а также сайтов этой тематики). Поиск, описание, помощь и обсуждение.
На этом сайте находится каталог cgi-скриптов (34 категории), который пополняется несколько раз в неделю.
Также предлагаю Вашему вниманию рассылку, посвященную новостям этого сайта и новым поступлениям скриптов - "Обзор CGI-скриптов".
Подписаться на нее можно здесь:
Адрес рассылки "Обзор CGI-скриптов" в Каталоге subscribe.ru: http://subscribe.ru/catalog/inet.review.cgi/
Архив рассылки "Обзор CGI-скриптов" находится на subscribe.ru по адресу:
http://subscribe.ru/archive/inet.review.cgi/
О рассылке
В связи с тем, что ко мне часто приходят письма вновь подписавшихся с просьбой выслать предыдущие номера рассылки или указать где их можно взять, я даю адреса на subscribe.ru связанные с моей рассылкой.
Домашняя страница этой рассылки в Каталоге subscribe.ru: http://subscribe.ru/catalog/comp.soft.prog.perlprog/, здесь же Вы можете и подписаться на данную рассылку.
Архив этой рассылки находится на subscribe.ru по адресу: http://subscribe.ru/archive/comp.soft.prog.perlprog/
Данная рассылка распространяется только через subscribe.ru.
Если Вам понравилась эта рассылка, и Вы считаете, что она может быть полезна и другим, то отправьте ее
своим друзьям.
Обращение к рекламодателям
Уважаемые господа! Если Вы хотите разместить свою рекламу на страницах этой рассылки, то обращайтесь со своими предложениями к ее автору, то есть ко мне, по адресу vitalij@newmail.ru и я сообщу Вам дополнительные сведения.
Ну, на этом позвольте на сегодня закончить. До новых встреч.
При подготовке данной рассылки были использованы следующие материалы:
1. "CGI Developer's Guide" Eugene Eric Kim
2. "Learning Perl" Randal Schwartz, Tom Christiansen & Larry Wall; 302 pages.
Second Edition, 1997
http://subscribe.ru/
E-mail: ask@subscribe.ru |
В избранное | ||