Внимание! Прочитайте, пожалуйста, текст в правой колонке (внизу).
Внимание! Прочитайте, пожалуйста, текст в правой колонке (внизу). Внимание! Прочитайте, пожалуйста, текст в правой колонке (внизу). Homepage Карта сайта Версия для печати

Джентльменский набор Web-разработчика   Ларри Уолл о Perl6   Наблы Система Orphus
 

6. Модуль CGI::WebIn, или предпоследний удар по тщеславию PHP

[5 сентября 2001 г.]

  Пользователь — не волк, в лес не убежит.
Распространенное заблуждение

Итак, мы худо-бедно (а может быть, все-таки толсто-богато, судя по ценности предыдущего материала?..) разобрались с тем, как избавиться от надоедливой 500-й ошибки при работе на Perl, а также о модуле CGI::WebOut, призванным сделать жизнь раем. Если помните, впереди еще две задачи, одна из которых сейчас успешно разрешится.

Лирическое отступление 
Прежде, чем читать дальше, пристегните ремни безопасности. Установка модуля CGI::WebIn, который описывается далее, сопряжена с риском. Риском полностью отказаться от PHP в своей работе и перейти на Perl. Я не шучу. На первых порах, если у вас нет наработок на Perl, это может действительно отрицательно сказаться на производительности труда.

Чтобы иметь хоть какой-то эталон, давайте посмотрим, что сделает PHP, если скрипту передадутся данные следующей формы:

<form action=script.php method=POST enctype=multipart/form-data>
<input type=text name=F1 value="1">
<input type=text name=F2[elt] value="2">
<input type=text name=F3[elt][subelt] value="3">
<input type=text name=F4[] value="4">
<input type=text name=F4[] value="5">
<input type=file name=F5>
</form>

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

$F1 === 1
$F2 === array(elt => 2)
$F3 === array(elt => array(subelt=>3))
$F4 === array(4,5)
$F5 === временное имя закачанного файла

Чайник 

Откуда взялся тройной знак равенства? Но ведь именно он обозначает в PHP оператор проверки на идентичность...

Что ж, мы видим, что PHP оказывается довольно услужливым, когда дело доходит до разбора данных формы. Ему даже все равно, каким образом — методом GET, POST или даже в кодировке multipart — пришли данные.

Теперь можно установить модуль CGI::WebIn и посмотреть, что он нам предоставляет. Вы можете, как обычно, скачать его из архива по адресу http://www.dklab.ru/chicken/mod/ppd (для Windows) или http://www.dklab.ru/chicken/mod/cpan (для Unix).

Чайник 

Если вы в недоумении и не знаете, как устанавливать модули в различных операционных системах, читайте об этом в пятой набле.

Модуль CGI::WebIn делает то же самое, что и PHP в приведенном выше примере. А именно, все переменные, пришедшие из формы, а также Cookies, он преобразует (по желанию) в переменные вызвавшего пакета. Итак, имея форму:

<form action=script.pl method=POST enctype=multipart/form-data>
<input type=text name=F1 value="1">
<input type=text name=F2{elt} value="2">
<input type=text name=F3{elt}{subelt} value="3">
<input type=text name=F4{} value="4">
<input type=text name=F4{} value="5">
<input type=file name=F5>
</form>
и написав в скрипте:
#!/usr/bin/perl -w
use CGI::WebIn(1);
мы получим переменные:
$main::F1 == 1
%main::F2 == (elt => 2)
%main::F3 == (elt => {subelt=>3})
%main::F4 == (4=>4, 5=>5) # Внимание!
$main::F5 == (file=>врем_имя, filename=>исх_имя, ...)

Здесь есть три торжественных момента.

  • Зачем мы написали 1 в скобках в предложении use CGI::WebIn(1)? Да затем, чтобы CGI::WebIn понял, что от него действительно ожидают создания и экспортирования переменных. Если не написать единички в скобках, модуль не будет экспортировать никаких полей формы, а просто поместит их в хэши %GET, %POST, %COOKIES и все вместе — в %IN. Нужно для справедливости сказать, что указанные 4 хэша будут доступны программе в любом случае.

    Чайник 

    В PHP, как известно, нет никаких пакетов и модулей, и все переменные бывают либо глобальными, либо локальными внутри функции. Что может быть неудобнее?.. Разве что отсутствие переменных вообще. С Perl ситуация совершенно иная, и термин «экспортирование» означает следующее. Когда мы создаем некоторый объект в программе — в частности, обычную скалярную переменную, — Perl выделяет для нее память и инициализирует. В дальнейшем можно на этот участок памяти ссылаться, причем ссылок может быть сколько угодно. Так что переменная внутри того или иного пакета — это всего лишь ссылка на созданный объект-хранилище. «Экспортировать переменную в какой-то пакет» означает лишь «создать в этом пакете ссылку на нее».

  • Каким еще может быть значение в скобках при подключении модуля CGI::WebIn? Например, строка-комбинация из букв "g", "p", "c" и "e". Первая буква означает, что будут экспортироваться поля, пришедшие методом GET, вторая — POST, третья, соответственно, — Cookies, и четвертая — переменные окружения. Например, "gpc" означает, что вначале будут обработаны GET-переменные, затем — POST (и в случае совпадения имен POST-переменная перепишет GET-переменную) и, наконец, Cookies. Кстати, указанная в примере единичка — это всего лишь сокращение для строки "gpce".

  • И, наконец, строчка, помеченная комментарием «Внимание!». Заметьте: в отличие от PHP, где пустые квадратные скобки в имени поля означают «создать очередной элемент массива», модуль CGI::WebIn воспринимает конструкцию Variable{}=value несколько иначе. А именно, он «понимает» ее так же, как Variable{value}=value. Это особенно удобно при обработке списков с множественным выбором и групп флажков:

    <select name=List{} multiple>
    <option value=1>Один
    <option value=2>Два
    <option value=3>Три
    </select>
    Если пользователь выберет элементы 1 и 3, то в программе создастся хэш %List, в котором будут два элемента с ключами 1 и 3, так что наличие одного из них проверяется элементарно:
    #!/usr/bin/perl -w
    use CGI::WebOut;
    use CGI::WebIn(1);
    if(exists $List{1}) { print "Выбрана цифра 1!" }

Вам не кажется, что уже настало время привести пример использования модуля CGI::WebIn в связке с CGI::WebOut? Что?.. Тогда приступим.

Лирическое отступление 
Я, правда, не могу знать наверняка, что вы ответили только что. Так что всех, кому первая попытка не удалась, а также заядлых приверженцев PHP, не желающих «читать эту ересь», прошу срочно закрыть глаза или нажать на кнопку справа от монитора. Знаете, такая большая, с лампочкой над ней...

#!/usr/bin/perl -w
use CGI::WebOut;
use CGI::WebIn(1);

# Зачем эти глупые строчки? Только для того, 
# чтобы обмануть Perl. Если их не написать, 
# скрипт будет весьма надоедливо сообщать о том, что 
# описанные ниже переменные используются лишь 
# один раз и "это, возможно, тупо" (possible typo).
our ($doGo,%Address,$Count); 

# Считаем, сколько раз этот пользователь 
# запустил скрипт (десятилетний Cookie).
SetCookie("Count",++$Count,"+10y");

# Кнопка нажата?.. Если да, то в переменной $doGo 
# (см. ниже) будет строка "Say hello".
if($doGo) {
    print "Hello from $Address{Russia}{Moscow}!";
}

# Теперь, скрепя сердце, печатаем форму, как это 
# делали еще наши деды. Такой код во множестве
# сердец вызывает заслуженное отвращение, но что 
# поделать - пока что у нас нет выбора.
print <<EOT;
    You have visited this page $Count times.
    <form action=$SCRIPT_NAME method=post enctype=multipart/form-data>
    <input type=text name="Address{Russia}{Moscow}" value="house">
    <input type=submit name=doGo value="Say hello">
    </form>
EOT

Ну что же, это уже почти PHP. Для полного расслабления нам не хватает лишь возможности вставлять код скрипта прямо в HTML — хотя бы с помощью все тех же тэгов <? и ?>. Если вы готовы к этому шагу, плавно переходите к следующей набле. В противном случае вернитесь назад и вспомните, зачем вообще затевалась «гонка за PHP».

 
Рекламный блок
   

Важное объявление:
    автор категорически против копирования и распространения в Интернете всех статей «Куроводства» с возрастом, меньшим 6 месяцев. Печальный опыт «расползания» чрезвычайно устаревших ошибочных версий статьи про Apache действительно объясняет такое решение.

Орфография на «Куроводстве»:
    если вы заметили орфографическую, стилистическую или другую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Выделенный текст будет немедленно отослан вебмастеру, а Вы даже ничего и не заметите — настолько быстро все произойдет.

На заметку:
    если вы уже вскипели насчет дизайна этой страницы, то присмотритесь повнимательнее к названию, почитайте FAQ, сходите по лебедевским местам, как это уже предлагалось выше. Можно ли считать пародию плагиатом? Надеюсь, что нет.

Параметры этой страницы
   
GZip

Ссылки от спонсоров
   


Дмитрий Котеров | 5 сентября 2001 г. ©1999-2016 | Генеральный спонсор: Хостинг «Джино» | Контакт Вернуться к оглавлению