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

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

4. Модуль CGI::WebOut,  или как подогнать Perl под PHP и откуда берется отвращение к CGI.pm

 
#!/usr/local/bin/perl -w
use CGI;
$q = new CGI;
print $q->header,
      $q->start_html('Трепещи, дизайнер'),
      $q->h1('CGI.pm идет!'),
      $q->end_html;

Ужасы и реалии модуля CGI.pm

Лирическое отступление 

Тише! Слышите?.. Ах, ну конечно — возмущенные крики поклонников модуля CGI.pm. Они восхищены приведенной выше цитатой, считая ее классическим образцом скрипта, но им не нравится подпись и вообще название этой наблы. Ну что же, граждане, попрошу вас развернуться на 180 градусов и идти назад, или хотя бы на время помолчать. Спасибо, так стало чуть лучше.

Хотя нет, не лучше. Теперь я слышу стоны. Стоны дизайнеров и HTML-верстальщиков. Это люди, воюющие на фронтах, далеких от страны программирования. Для них приведенный выше код — как китайская грамота. И они задыхаются от того, что не могут легко изменить внешний вид страницы, сгенерированной программой. Мы, программисты, должны испытывать милосердие по отношению к таким людям. А значит, во всем стараться им помогать. Так что перейдем к делу.

Итак, приблизим Perl по удобству программирования к PHP, сохранив в то же время все его лучшие качества. Для этого нужно проделать 3 шага:

  1. избавиться от надоедливой 500-й ошибки;
  2. научиться принимать данные из форм так же легко, как это позволяет делать PHP;
  3. добиться того, чтобы в скриптах работали псевдо-PHP тэги <? и ?>.

Комплексная проблема, в отличие от такого же обеда, смертельна не всегда. В нашем случае мы сначала рассмотрим мощный модуль CGI::WebOut, который решает первую часть проблемы. Следующие наблы будут посвящены оставшимся задачам.

В предыдущей набле мы в деталях рассмотрели способ, позволяющий побороть 500-ю ошибку и выводить все предупреждения прямо в окно браузера, что неоценимо при отладке скриптов. Чтобы не писать весь этот код каждый раз, я сгруппировал его и множество других возможностей в модуле CGI::WebOut, который вы можете скачать из архива по адресу http://www.dklab.ru/chicken/mod/ppd (для Windows) или http://www.dklab.ru/chicken/mod/cpan (для Unix). О том, как устанавливать модули в различных операционных системах, читайте в следующей набле.

Предположим, CGI::WebOut установлен. На примерах посмотрим, что мы теперь можем делать.

Избавление от 500-й ошибки, печать предупреждений в браузер

#!/usr/bin/perl -w
use CGI::WebOut;
# ух ты, мы можем даже не выводить Content-type!
print "Hello world!"; 
warn "Последнее предупреждение.\n";
# попробуйте раскомментировать следующую строчку
# (вызов несуществующей функции, порождающий ошибку):
#no_such_function();

Вывод заголовков уже после вывода тела

#!/usr/bin/perl -w
use CGI::WebOut;
# указываем, что заголовки могут выводиться и после тела
NoAutoflush();
print "Hello world! "; 
# добавляем заголовок во время вывода тела!
Header("Content-type: text/plain");
print "I am alive!"; 

Временный перехват выходного потока

#!/usr/bin/perl -w
use CGI::WebOut;
print "Hello world! "; 
# все, что выводится якобы в браузер, попадет в $st
my $st=grab {
    print 'Этот текст сразу в браузер не попадет - ';
    print 'он будет помещен в переменную $st';
};
print "I am alive! ";
print "Перехваченная строка: '$st'";

Многоуровневый перехват

#!/usr/bin/perl -w
use CGI::WebOut;
my $st=grab {
    print "Этот текст сразу в браузер не попадет - ";
    # нам все равно, был ли вывод уже перехвачен
    my $s=grab {
        print 'А вот этот текст не попадет в $st -';
        print 'Он будет сохранен в $s';
    };
    print 'он будет помещен в переменную $st. ';
    print "Текст из s: '$s'";
};
# не забудьте только ";" после последней "}"!
print "Перехваченная строка: '$st'";

Работа с исключениями

#!/usr/bin/perl -w
use CGI::WebOut;
# исключение (фатальная ошибка), порожденное 
# в блоке try, передается коду в блоке catch.
try {
    require No_such_module;
    # можно сгенерировать исключение программно
    throw "Исключение"; 
} catch {
    # объект-исключение в $_
    warn "Не удалось подключить модуль: $_\n";
} warnings {
    # ошибки и предупреждения в @_
    warn "Во время подключения произошли ошибки ".
         "и предупреждения: ".join("\n",@_);
};
# блоки catch и warnings можно опускать:
try {
    Do_some_dangerous_work();
};

Чайник 

Ну что, все? Почти. Еще чуть-чуть, потерпите.

Другие возможности

#!/usr/bin/perl -w
use CGI::WebOut;
# теперь можно выводить заголовки во время вывода тела
NoAutoflush();

# отключаем кэширование в браузере
NoCache();

# или можем перенаправить на другую страницу
Redirect("http://www.perl.org");
exit(); # не забудьте завершить скрипт после редиректа!

# или же немедленно посылаем накопленные заголовки 
# и тело документа в браузер, не дожидаясь конца скрипта
Flush();

Ну вот, теперь достаточно. Казалось бы, не так уж и много, но это действительно все, что может когда-либо понадобиться при работе с выходным потоком CGI. Кстати говоря, многих возможностей, которые поддерживаются модулем CGI::WebOut, в PHP просто нет.

У нас остались еще две проблемы, помните?.. Следующая — обработка данных входного потока с помощью модуля CGI::WebIn.

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

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

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

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

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

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


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