Статические и динамические веб страницы. Веб-программирование на perl и шаблоны html страниц. Разработка модели базы данных

Изо дня в день работая над обновлением содержимого своего Web-сайта, насыщая его интересными материалами, вы, вероятно, задумываетесь о том, что ежедневно создаются сотни новых Web-сайтов, которые также ежедневно пополняются сотнями новых документов. Как создаются все эти новые массивы страниц и каким образом они так быстро обновляются? Все это не так сложно, как кажется на первый взгляд, поскольку здесь используется концепция динамических Web-страниц.

В этой статье мы рассмотрим этапы создания механизма публикации на Web-сайте пресс-релизов. Наш сайт будет соединять «на лету» пресс-релизы, хранящиеся в базе данных, с шаблонными Web-страницами. Мы не ставили целью ознакомить читателей с основами средств разработки Web-сайтов, поскольку об этом написано множество книг и статей. Данная статья предназначена в основном для тех пользователей, которые уже имеют опыт создания Web-страниц и простых сайтов. Наша главная цель - показать, как начать разрабатывать свой первый динамический Web-сайт. Для понимания статьи желательно иметь базовые знания об архитектурах информационных систем, о языке разметки гипертекста (HTML) и языке программирования Perl . Для создания этого сайта мы воспользуемся тремя мощными открытыми технологиями: Apache, MySQL и Perl/DBI.

Что такое статический Web-сайт?

Перед тем, как погрузиться в разработку динамического Web-сайта, важно понять, что представляют собой статический Web-сайт и статические Web-страницы, составляющие его основу. Статические Web-страницы создаются вручную, потом сохраняются и загружаются на сайт. Всякий раз, когда требуется изменить содержимое такой страницы, пользователь модифицирует ее на своем рабочем компьютере, применяя, как правило, HTML-редактор, сохраняет ее и затем заново загружает на Web-сайт. Внимательно присмотревшись к какому-нибудь порталу, допустим к CNN.com или BBC.co.uk, можно подумать, что для обновления содержимого своих сайтов эти компании привлекают армию верстальщиков. На самом же деле существует лучший способ - использование концепции динамического Web-сайта.

Что такое динамический Web-сайт?

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

Создание динамического сайта

Первое, что нужно для создания динамического сайта, - это Web-сервер, например Apache.

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

Немногие из принимаемых в бизнесе стратегических решений столь же значимы, как выбор платформы для Web-сервера. Характеристики сервера - это чрезвычайно важный фактор, определяющий надежность узла, его «отзывчивость» на запросы клиентов, а также то, какие усилия необходимо предпринимать для поддержания его в рабочем состоянии. При правильном выборе компонентов и качественном проекте Web-узел может стать для клиентов и партнеров новым, более удобным способом взаимодействия с вашей компанией. Перегрузка Web-сервера может привести к тому, что сервер баз данных или какой-либо иной ресурс станет недоступным для клиентов.

Крупные компании до недавнего времени делали ставки на Microsoft Internet Information Server, Netscape FastTrack, IBM WebSphere, а Apache в основном использовался небольшими компаниями. Однако сейчас ситуация несколько изменилась, и Apache начинает поддерживать работоспособность некоторых крупных Интернет-проектов, в частности Yahoo.

Полную версию статьи вы можете найти на нашем CD-ROM.

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

Далее вам нужно решить, как вы собираетесь хранить информационное наполнение (контент), которое отображается на Web-странице. В данной статье на конкретном примере мы покажем, как создать базу данных в СУБД MySQL, которая позволит нам разбить Web-контент на таблицы, содержащие поля и записи с данными. Поле - это дискретная единица данных в таблице. Например, мы можем создать таблицу tbl_news_items с полями col_title, col_date, col_fullstory, col_author. СУБД MySQL - отличный выбор для создания такой базы данных вследствие простоты в использовании и администрировании, свободной распространяемости для разных платформ, включая Linux и Windows, и быстро растущей популярности.

После этого мы создадим динамические шаблонные страницы на HTML. Чтобы разработать приложения для взаимодействия с базой данных и шаблонами, мы воспользуемся языком Perl.

На самом деле нам необходимо создать три Perl-программы, или скрипта: один будет отображать ссылки на все имеющиеся пресс-релизы (pr-list-dbi.pl), другой - содержимое выбранного пресс-релиза (pr-content-dbi.pl), а третий позволит нам добавить свежий пресс-релиз в базу данных (pr-add-dbi.pl). Работу по верстке можно возложить на любимый HTML-редактор, например, Allaire HomeSite (http://www.allaire.com/). Только помните, что при создании шаблона необходимо оставлять пустые области, в которые будет вставляться динамическое наполнение (естественно, переменной длины).

После разработки общего дизайна для своих пресс-релизов просто вставьте в указанные выше пустые области специальные ключевые слова (см. об этом ниже). Как только пользователь запросит какой-либо пресс-релиз, Web-сервер обработает Perl-код и заменит ключевые слова в шаблонах информационным наполнением, извлеченным из базы данных, то есть каким-то конкретным пресс-релизом.

И последнее, что нужно сделать, - загрузить ваши шаблоны на Web-сервер в определенные директории. Можно воспользоваться FTP-клиентом CuteFTP (http://www.cuteftp.com/), но мы предпочитаем использовать файловую оболочку FAR. Две важные вещи, которые следует запомнить: первое - файлы шаблонов должны содержать имена, оканчивающиеся на.pl, и второе - они должны иметь право на выполнение (в UNIX-системах надо выполнить команду chmod 0755 имя_шаблона.pl). Это все!

Добавление функциональности

Не представляет особых сложностей добавление функциональных возможностей к механизму публикации пресс-релизов. Можно отсортировать ссылки на доступные в базе данных пресс-релизы по дате или названию, группируя их по годам. Или, например, вы захотите отобразить случайный пресс-релиз на вашей Web-странице, время от времени предоставляя его информацию посетителям независимо от того, когда он был реально опубликован. Но скорее всего самой важной и полезной функциональностью будет добавление HTML-формы для ввода содержимого пресс-релиза и разработки CGI-программы на Perl в целях обработки этой формы и последующего размещения документа в базе данных. Напомним, что CGI (Common Gateway Interface) - протокол, механизм, или формальное соглашение между Web-сервером и отдельной программой. Сервер кодирует входные данные, например HTML-формы, а программа CGI декодирует их и генерирует поток выходных данных. В спецификации протокола ничего не сказано о каком-либо определенном языке программирования. Поэтому программы, соответствующие этому протоколу, могут быть написаны практически на любом языке - на C, C++, Visual Basic, Delphi, Tcl, Python или, как в нашем случае, на Perl.

Подведем некоторые итоги. Надеемся, что эта статья поможет вам оценить преимущества концепции динамических Web-страниц перед статическими. Применение данной концепции приведет к сокращению ручной работы, поможет распределить рабочую нагрузку сервера и позволит быстро увеличить количество информационного наполнения сайта. Комбинация из Apache, MySQL и Perl предоставит практически бесплатную, простую в использовании, гибкую в установке и настройке кросс-платформенную и масштабируемую среду разработки. Здесь мы не будем рассматривать особенности их установки, так как, во-первых, на это попросту не хватит места, отведенного для данной статьи, а во-вторых, каждое из этих средств поставляется вместе с весьма подробной документацией.

Создание базы данных в СУБД MySQL

Разработка модели базы данных

Первым и наиболее важным действием при создании базы данных является разработка ее модели. Итак, приступаем.

Шаг 1

Нам нужно как-то назвать базу данных. Назовем ее db_website.

Шаг 2

Необходимо определить, что именно будут содержать таблицы базы данных. В БД могут входить сотни таблиц. Сначала нам потребуется всего одна таблица для хранения наших пресс-релизов. Назовем ее tbl_news_items.

Шаг 3

Следует определить поля, которые будет содержать наша таблица. Эти поля будут являть собой все элементы пресс-релиза. В нашем примере используются пять полей: col_id (числовой идентификатор пресс-релиза), col_title (название), col_date (дата публикации), col_fullstory (содержимое), col_author (имя автора). Поле col_id будет содержать уникальный идентификатор, по которому пользователь сможет запрашивать содержимое определенного пресс-релиза.

Создание базы данных

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

Прежде всего вам обязательно следует знать основы языка запросов SQL (Structured Query Language). В поставку СУБД MySQL входит полное описание поддерживаемой спецификации SQL. Этот язык несложен для постижения, поскольку его операторы и их конструкции легко понять и запомнить. Для работы вам потребуются операторы создания (CREATE или INSERT), выборки (SELECT) и удаления (DROP или DELETE) данных, а также их изменения (UPDATE, MODIFY). В конкретных примерах мы воспользуемся только некоторыми из них.

Чтобы не рассматривать установку пользовательских учетных записей (user accounts) и назначение необходимых прав доступа, предположим, что вы используете учетную запись администратора (root).

Шаг 1

Откройте терминальное окно (если вы работаете в графической оболочке X Window ОС Linux или в ОС Windows 9x/NT/2000) и установите соединение с СУБД MySQL, введя в командной строке mysql. В ответ вы должны получить приглашение для ввода команд mysql>.

Шаг 2

Создадим нашу базу данных, введя:

CREATE DATABASE db_website;

После ввода каждой команды не забывайте печатать символ (;). Он очень важен, поскольку посылает MySQL сигнал конца ввода команды.

Use db_website;

Шаг 4

Создадим таблицу tbl_news_items, где определим тип данных, которые будут храниться в ее полях. Введите:

1. CREATE TABLE tbl_news_items (2. col_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 3. col_title VARCHAR(100), 4. col_author VARCHAR(100), 5. col_body TEXT, 6. col_date DATE 7.);

Шаг 5

Теперь, когда мы создали таблицу для хранения наших данных, нам нужно заполнить ее какими-то примерными данными. Заметьте, что в нижеследующей команде мы не будем определять поле col_id, потому что оно заполняется автоматически по мере добавления новых данных. Также имейте в виду, что синтаксис для даты - <год/месяц/день>. Итак, в командной строке mysql> введите следующую команду.

8. INSERT INTO tbl_news_items (col_title, _ col_author, col_body, col_date) 9. VALUES (10. ‘Мой первый пресс-релиз’, 11. ‘Ваше Имя’, 12. ‘Этот пресс-релиз хранится в БД MySQL’, 13. ‘2001/4/15’ 14.);

Введите еще несколько подобных запросов для вставки. Чтобы просмотреть то, что хранится в базе данных, в командной строке mysql> введите:

SELECT * FROM tbl_news_items;

Создание динамических Web-страниц на Perl

Подготовка к работе

Для запуска Perl-программ понадобится интерпретатор Perl версии 5.005 или 5.6 дистрибутивов Perl Standard или ActiveState Perl для UNIX или Win32. Если вы будете заниматься разработкой приложений для функционирования под Win32, то пакет от ActiveState несколько удобнее в использовании, к тому же в него входит утилита PPM для установки дополнительных модулей.

Для организации взаимодействия наших Perl-программ с СУБД MySQL необходимо, чтобы в поставку Perl входил модуль DBI. Поскольку модуль в основном ничего сам не делает, а перекладывает все операции по взаимодействию с базами данных на соответствующий им драйвер, то требуется установка библиотеки DBD-Mysql (драйвер к БД MySQL для модуля DBI). Как заявил Тим Бьюнс (Tim Bunce), автор и разработчик указанного модуля, «DBI - это API-интерфейс для организации доступа к базам данных из Perl-программ. Спецификация DBI API определяет набор функций, переменных и правил, используемых для прозрачного интерфейса с базами данных».

Концепция драйверов баз данных весьма удобна, поскольку в своем Perl-приложении вы используете стандартные для DBI вызовы, которые затем переадресуются модули соответствующему драйверу, а тот, в свою очередь, уже напрямую будет взаимодействовать с БД, не требуя от вас изучения технических особенностей каждой конкретной СУБД. Таким образом, существуют драйверы DBD::Sybase, DBD::Oracle, DBD::Informix и т.д. (рис. 1 , ).

Немного выйдем за рамки тематики статьи. Допустим, что в поставку DBI не входит драйвер для специфической СУБД. В данном случае на помощь придет мост DBD-ODBC. Достаточно создать новый источник данных (Data Source Name) для драйвера ODBC (Open DataBase Connectivity), где нужно выбрать тип этой СУБД, адрес хоста, по которому надо установить соединение, имя базы данных и авторизационные данные, то есть имя пользователя и пароль (рис. 3). И затем, используя модуль DBI, взаимодействовать с базой данных. Кроме того, как правило, в стандартную поставку ActiveState Perl входит модуль Win32::ODBC (Win32-ODBC). Работа с ним немного отличается от работы с DBI, но в целом очень похожа. Разница лишь в том, что Win32::ODBC - модуль только для Win32-систем и позволяет работать с «родными» функциями ODBC более эффективно, чем DBD::ODBC.

Между ODBC и DBI можно провести параллель. DBI - это аналог ODBC Administrator (менеджера драйверов баз данных). Каждый DBD-драйвер по своим функциям соответствует ODBC-драйверу. Может смутить лишь тот факт, что существует, как говорилось выше, драйвер DBD::ODBC. Но он всего лишь позволяет установить связь DBI с ODBC-драйверами.

Для установки DBI и DBD-Mysql, с помощью утилиты PPM в среде Win32 введите в командной строке:

Ppm install DBI

Обратите внимание, что в этот момент ваш компьютер должен быть подключен к Интернету. Если же соответствующий модуль имеется у вас на локальном диске, воспользуйтесь справочной информацией, введя команду:

Ppm help install

Для пользователей UNIX-систем установка модуля DBI будет проходить практически так же, как и установка других Perl-модулей:

Tar –zxvf DBI-1.06.tar.gz cd DBI-1.06/ perl Makefile.PL make make test make install

Можно также воспользоваться оболочкой CPAN. Если же на вашем компьютере установлена UNIX-версия пакета от ActiveState, то можно работать и с установочной утилитой PPM. Иногда бывает, что оболочки CPAN и PPM не функционируют, если в сети предприятия, к которой подключен ваш компьютер, установлен брандмауэр, или сетевой экран (firewall). В данном случае вам помогут только модули с исходными текстами, загруженные вручную. Для их установки и подключения к Perl или Apache потребуется интерпретатор Perl, компилятор C/C++ или GCC/PGCC и какая-либо из утилит-сборщиков make (из поставки одного из клонов UNIX, а также Microsoft Visual C++), nmake или dmake. Таким образом, процедура установки модулей несколько усложняется. Почти с каждым из них поставляется документация по «сборке», благодаря которой у вас не должно возникнуть особых трудностей.

Вывод списка статей

Теперь, когда у вас есть работающая база данных с пресс-релизами, можно без особых проблем подключить ее к Web-странице. Начнем с создания простейшей страницы, которая отображает список всех имеющихся пресс-релизов. Заметьте, что по умолчанию Web-сервер Apache «думаеть», что все ваши документы должны находится в его директории htdocs, а исполняемые файлы - в cgi-bin. Следовательно, необходимо поместить все файлы с расширением.pl в каталог cgi-bin. В свою очередь, создаваемые файлы HTML-шаблонов нужно разместить в каталоге tpl. Иерархия каталогов будет выглядеть следующим образом:

/ (корень любого диска) /local /local/usr /local/usr/bin /local/usr/cgi-bin /local/usr/htdocs /local/usr/tpl

Для систем DOS/Windows путь к cgi-bin может выглядеть так:

C:\local\usr\cgi-bin

Шаг 1

Используя свой любимый текстовый редактор, создайте файл pr-list-tpl.htm:

15. 16. 17. Пресс-релизы 2001 18. 19. 20. @BLOCK@ 21. 22.

Этот файл предназначен для отображения списка всех доступных пресс-релизов.

Шаг 2

Создайте файл pr-list-block-tpl.htm, который будет отображать каждый блок с найденным пресс-релизом в виде таблицы:

23.

24. 25. 26.
@TITLE@
@AUTHOR@, _ @DATE@

Шаг 3

Создайте файл pr-content-tpl.htm, который будет отображать содержание пресс-релиза:

27. 28. 29. Press-releases 2001: @TITLE@ 30. 31. 32.

@TITLE@

33. 34. 35. 36. 37.
@TITLE@
Author: @AUTHOR@ Date: @DATE@
@BODY@
38. Show the list of press-releases.. 39. 40.

Шаг 4

Создайте Perl-скрипт pr-list-dbi.pl, который будет читать данные из базы данных db_website и, используя шаблонные HTML-файлы, отображать список пресс-релизов (текст этого скрипта вы сможете найти на нашем компакт-диске).

А теперь пройдемся по листингу кода и рассмотрим, как работает программа вывода списка пресс-релизов.

Строки 1-9 представляют собой как бы инициализирующий блок, в котором объявляются все глобальные переменные и константы:

41. #!/local/usr/bin/perl 42. 43. use DBI; 44. $dbh = DBI->connect(‘dbi:mysql:db_website’,’root’,’’); 45. $path = "/local/usr/tpl"; 46. $TPL_LIST = "$path/pr-list-tpl.htm"; 47. $TPL_LIST_BLOCK = "$path/pr-list-block-tpl.htm"; 48. 49. print "Content-type:text/html\n\n";

Сперва мы сообщаем Web-серверу Apache путь, указывающий, где находится интерпретатор Perl, который запускается при запросе скрипта, проверяет его на ошибки и затем выполняет его. Далее мы объявляем модуль DBI (DataBase Interface), методы которого будут использоваться в программе для взаимодействия с базой данных (строка 3). Затем мы устанавливаем соединение с нашей базой данных db_website (4), указывая в качестве входного имени пользователя root (администратор), а в качестве пароля пустую строку (значение, принятое по умолчанию). В переменной $path указываем путь, по которому находятся файлы HTML-шаблонов (5). В переменных $TPL_LIST и $TPL_LIST_BLOCK соответственно указываем их имена (6, 7). Потом, сообщаем Web-серверу, что все исходящие данные должны представляться в MIME-формате text/html для вывода HTML-потока в пользовательский браузер (9).

Строки 11-22 представляют собой тело программы:

50. 51. open (L, "$TPL_LIST"); 52. while ($line1=) { 53. chomp($line1); 54. if ($line1=~/\@BLOCK\@/) { 55. read_db(); 56. ins_data(); 57. } else { 58. print "$line1\n"; 59. } 60. } 61. close(L); 62. 63. $dbh->disconnect;

Открываем файл-шаблон pr-list-tpl.htm (11) и в цикле (12-20) просматриваем его, записывая каждую считанную строку в переменную $line. Во время каждой итерации производим проверку на наличие в этой строке ключевого слова @BLOCK@ (14-19), означающего, что в данном месте надо вставить блок с пресс-релизом. Как только оно найдено, вызываем процедуры read_db() и ins_data().

Строки 26-39 - тело процедуры read_db(), предназначенной для считывания содержимого таблицы tbl_news_items, в которой хранятся наши пресс-релизы:

64. 65. 66. sub read_db { 67. $c=0; 68. my($sql) = "SELECT * FROM tbl_news_items"; 69. $rs = $dbh->prepare($sql); 70. $rs->execute; 71. while (my $ref = $rs->fetchrow_hashref()) { 72. $id[$c] = "$ref->{‘col_id’}"; 73. $title[$c] = "$ref->{‘col_title’}"; 74. $author[$c] = "$ref->{‘col_author’}"; 75. $date[$c] = "$ref->{‘col_date’}"; 76. $c++; 77. } 78. $rs->finish(); 79. }

Инициализируем счетчик $c=0, составляем запрос выборки всех данных из таблицы (28), выполняем запрос (29, 30) и получаем данные в рекордсет (recordset - набор записей) $rs. Затем в цикле (31-37) извлекаем данные из рекордсета, используя метод fetshrow_hashref и возвращая ссылку на ассоциативный массив %ref (31), содержащий имена и значения полей текущей записи. Записываем извлеченные данные (32-35) в соответствующие их типам обычные массивы @id, @title, @author и @date. Закрываем рекордсет (38).

Строки 41-53 - тело процедуры ins_data(), реализующей вставку извлеченных из БД данных в исходящий поток данных; строки 55-63 - тело процедуры pr_block(), вызываемой в цикле из процедуры ins_data():

80. 81. sub ins_data { 82. $toread = "pr-read-dbi.pl"; 83. for ($i=0; $i<$c; $i++) { 84. $line = &pr_block; 85. 86. $line =~ s/\@NUMBER\@/$id[$i]/; 87. $line =~ s/\@TITLE\@/$title[$i]/; 88. $line =~ s/\@AUTHOR\@/$author[$i]/; 89. $line =~ s/\@DATE\@/$date[$i]/; 90. $line =~ s/\@READ\@/$toread/; 91. print "$line"; 92. } 93. } 94. 95. sub pr_block { 96. my($block) = ‘’; 97. open (B, "$TPL_LIST_BLOCK"); 98. while ($line=) { 99. $block = $block.$line; 100. } 101. close(B); 102. return ($block); 103. }

Итак, получив в результате выполнения процедуры read_db() максимальное значение счетчика $c, в цикле (43-52) мы запускаем процедуру pr_block(), которая читает содержимое HTML-шаблона pr-list-block-tpl.htm и записывает его в переменную $block (59), значение которой затем возвращается (62) в переменную $line (44) процедуры ins_data(). Далее в этом же цикле мы заменяем (46-50) найденные в исходящем потоке $line ключевые слова @NUMBER@, @TITLE@, @AUTHOR@, @DATE@, @READ@ на соответствующие данной итерации цикла ($i) значения массивов @id, @title, @author, @date и переменной $toread.

Вывод текста пресс-релиза

После того как мы вывели список всех имеющихся в базе данных пресс-релизов (рис. 4), нужно дать пользователю возможность просмотреть текст какого-нибудь из них (соответствующий скрипт вы также сможете найти на нашем компакт-диске).

Новый скрипт pr-read-dbi.pl будет незначительно отличаться от уже созданного нами pr-list-dbi.pl.

Данный листинг на 98% походит на листинг 1, хотя, имеет некоторые незначительные отличия:

  • подключена библиотека CGI для считывания параметра id (9) из строки запроса (например, http://localhost/cgi-bin/pr-content-dbi.pl?id=1);
  • применяется всего один HTML-шаблон (pr-content-tpl.htm);
  • запрос к базе данных дополнен условным SQL-оператором WHERE для выборки всех данных, соответствующих определенному пресс-релизу по идентификатору col_id;
  • из БД также считывается поле col_body с текстом выбранного пресс-релиза.

Создание нового пресс-релиза

Расширим функциональность нашей системы, добавив возможность создания новых пресс-релизов, без необходимости непосредственной работы с базой данных для пополнения таблицы tbl_news_items новой информацией.

Итак, новая Perl-программа (которая, как и предыдущие две, находится на компакт-диске) будет отличаться от предыдущих прежде всего тем, что предназначена не для отображения данных, а для их добавления в БД. Следовательно, мы должны несколько изменить часть, отвечающую за взаимодействие с БД, применив SQL-запрос INSERT и соответствующие ему операторы модуля DBI.

Строки 12-18 - это тело основной программы:

12. if ($cmd ne "add") { 13. &show_form; 14. } else { 15. $dbh = DBI->connect(‘dbi:mysql:db_website’, _ ’root’,’’); 16. &add_pr; 17. dbh->disconnect; 18. }

Здесь мы проверяем, поступила ли команда на добавление пресс-релиза в базу данных. Как только она поступила, устанавливаем соединение с БД (15), выполняем подпрограмму app_pr() (16) и завершаем соединение (17). Если же команды не было, то просто отображаем форму заполнения (13) для данных пресс-релиза - процедура show_form().

Строки 20-36 - это тело процедуры добавления пресс-релиза pr_add():

19. 20. sub add_pr { 21. $title = $q->param("pr_title"); 22. $author = $q->param("pr_author"); 23. $body = $q->param("pr_body"); 24. $body =~ s/\r\n/
/g; 25. 26. my($sql) = "INSERT INTO tbl_news_items (col_title,col_author,col_body,col_date) VALUES (\’$title\’,\’$author\’,\’$body\’,CURDATE())"; 27. $rs = $dbh->do($sql); 28. 29. if ($@) { 30. $rc = $dbh->rollback; 31. } else { 32. $rc = $dbh->commit; 33. } 34. 35. print "Location: /cgi-bin/pr-list-dbi.pl\n\n"; 36. }

Сперва обрабатываем данные формы (22-25), составляем SQL-запрос (27) и выполняем его (27) с помощью DBI-метода $dbh->do(). Поскольку здесь производится процедура вставки данных в БД, то нужно позаботиться о возможности отмены операции в случае сбоев. Для этого мы вставили код отмены транзакции и отката в предыдущее состояние (30-34). При сбое при выполнении $dbh->do() отменяем сделанные изменения (31). Если же сбоя не произошло, то подтверждаем сделанные изменения (33). Далее после всех действий просто переходим на страницу со списком всех пресс-релизов (36).

Строки 37-55 - это тело процедуры вывода формы для ввода информации о новом пресс-релизе (используется HTML-шаблон, имя которого задано в переменной $TPL_INSERT, pr-add-tpl.htm):

37. 38. sub show_form { 39. print "Content-type:text/html\n\n"; 40. 41. open (L, "$TPL_INSERT"); 42. while ($line=) { 43. chomp($line); 44. if ($line=~/\@/) { 45. if ($line=~/\@ADD\@/) { 46. $toadd = "pr-add-dbi.pl"; 47. $line =~ s/\@ADD\@/$toadd/; 48. } else { 49. $tolist = "pr-list-dbi.pl"; 50. $line =~ s/\@LIST\@/$tolist/; 51. } 52. } 53. print "$line\n"; 54. } 55. close(L);

Перегрузка системы

Поскольку вы разрабатываете динамический Web-сайт, то соответственно количество информации на нем может расти весьма быстро. Кроме того, по мере роста популярности вашего ресурса растет и число его посетителей, что может привести к перегрузкам сервера, то есть к понижению производительности системы. Перед тем как начать поиски путей увеличения мощности аппаратных средств и пытаться найти конфигурацию новой системы, можно попробовать устранить одну из возможных причин чрезмерного потребления оперативной памяти. Виновником может оказаться тот же Perl. Дело в том, что каждый раз при обращении к тому или иному Perl-скрипту, Web-сервер загружает интерпретатор в оперативную память (он занимает от 500-1000 Кбайт на жестком диске), а последний разбирает программу от начала до конца в поисках синтаксических ошибок. После этого он вновь читает ее, инициализируя переменные и функции, считывает вводимые данные (параметры), обрабатывает и возвращает результаты. Представляете, что происходит, если одновременно пресс-релизы хотят просмотреть сотни посетителей вашего сайта?

Для ускорения этого процесса созданы специальные решения, представляющие собой дополнительные модули для Web-сервера Apache - mod_fastcgi и mod_perl.

Модуль FastCGI (mod_fastcgi) предполагает широкое применение средств обмена данными между работающими процессами (задачами) операционной системы. В начале своей работы Web-сервер активирует CGI-программу и оставляет эту программу и несколько ее копий работающими в фоновом режиме. Любые запросы к программе будут просто переданы уже активным копиям, что избавит сервер от дополнительной нагрузки, связанной с повторной активацией процесса.

Модуль mod_perl позволяет загрузить Perl в оперативную память в то же адресное пространство, что и сам Web-сервер Apache, и оставить Perl в памяти до завершения работы последнего, не позволяя загружать очередную копию интерпретатора при обращении к CGI-программе. Этот модуль применяется чаще, чем FastCGI, поскольку не требует никаких изменений в программе.

КомпьютерПресс 6"2001

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

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

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

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

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

Предположим, 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 .

Страницы делятся на статические и динамические по поведению документа в браузере. С другой стороны эти понятия часто используют и в другом смысле. Документы также делятся на статические и динамические по способу создания документа.

По поведению документа в браузере пользователя, различают:

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

Динамика на веб страницах реализована при помощи скриптов, которые выполняются браузером. Многие элементы языка html поддерживают определение обработчиков событий. Например, можно задать обработку события "нажатия кнопки мыши" на картинке. Тогда если пользователь кликнет на эту картинку, вызовется определенный для этого обработчик.

Это может звучать несколько запутано, но не переживайте. Когда вы с этим столкнетесь - все будет проще.

Самый распространенный язык для создания динамики веб страниц - это JavaScript. (Не путайте с языком программирования Java. Это две совершенно разные сущности.)
Реже используется VBscript(visual basic script). (Microsoft как всегда пошла своим путем.)

По способу создания документы делят опять на статические и динамические.

Статическими называют страницы, если они лежат на сервере в html виде.
А динамическими называют те, которые генерируются "на лету" по запросу браузера.

Как легко увидеть, если на сервере лежит обычная html страница, то такой подход сильно ограничен. Например, у вас есть интернет-магазин, и вы добавили новый товар. Если ваш магазин состоит из "статических" html страниц, то вы должны вручную подправить несколько других страничек. Как минимум это каталог товаров и, наверное, форму заказа. Если у вас кончился какой-либо товар, то опять надо обновлять сайт. Это очень неудобно. Поэтому вы не найдете ни одного интернет магазина на html. (Хотя и можно придумать систему, которая автоматически перегенирирует сайт при изменении товара. Но это не очень элегантное решение и я о таком никогда не слышал).

Если ваш сайт содержит часто меняющийся контент (content - информация на сайте), то вам на помощь придут скрипты, выполняющиеся на сервере . И это ключевое отличие этих скриптов, от описанных ранее (тех, что написаны на JavaScript). Работает это следующим образом:

  1. Браузер запрашивает у сервера документ
  2. Сервер определяет, что документ является скриптом и запускает его на выполнение
  3. Скрипт генерирует html страницу
  4. Сервер отправляет сгенерированную страницу браузеру, так что тот и не догадывается, что на сервере отработал скрипт

Существует несколько языков программирования, на которых могут писать скрипты, которые генерируют "динамические" страницы. Самые распространенные из них:

  1. Python
  2. Бинарный код (программа на Си или С++ скомпилированная в исполняемый код)

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

Как правило если вы видите, что адрес страницы заканчивается на.html или.htm, то это обычная статическая страница. (Можно конечно настроить сервер так, чтобы он исполнял скрипты, которые заканчиваются на эти же окончания, только это не практично. Все таки.html и.htm - это стандарт и переопределять эти окончания не стоит.) Если же вы видите любое другое окончание, то это скорее всего скрипт. Например, скрипты на языке PHP имеют обычно расширение.php, на языке Perl - .pl, ASP - .aspx
Если же адрес не содержит имени страницы, то сервер будет использовать документ заданный по умолчанию (обычно это либо index.html либо index.htm либо index.php).

Надо сказать, что сейчас все больше набирает силу гибридная система. Название у нее, как у голландского футбольного клуба - AJAX, что означает: Asyncronous JavaScript And XML (Как расшифровывается название голландского клуба я не знаю:)). Эта технология позволяет скриптам на JavaScript обращаться к какому либо скрипту на сервере и получать информацию с сервера. Это в свою очередь, дает пользователю гибкость и позволяет перезагружать только часть содержимого страницы, а не всю ее полностью (что значительно экономит трафик).

Выводы

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

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

Александр Архипов

)
From: http://cgiscripts.r2.ru Date: Mon, 23 Feb 2004 14:31:37 +0000 (UTC) Subject: йУРПМШЪПЧБОЙЕ HTML::Mason РТЙ УПЪДБОЙЙ УБКФБ. пТЙЗЙОБМ: http://cgiscripts.r2.ru/docs/mason.shtml уБКФ У РПНПЭША HTML::Mason уФБФШС ПРХВМЙЛПЧБОБ Ч ЦХТОБМЕ рТПЗТБННЙУФ (http://www.programme.ru/) 04.2002 чЧЕДЕОЙЕ йЪ-ЪБ УМПЦОПУФЙ УПРТПЧПЦДЕОЙС, ОЕДПУФБФПЮОПК ЗЙВЛПУФЙ Й ПЗТБОЙЮЕООПК ЖХОЛГЙПОБМШОПУФЙ ЮЕМПЧЕЮЕУФЧП ДБЧОП ХЦЕ ПФЛБЪБМПУШ ПФ УФБФЙЮЕУЛЙИ HTML-УФТБОЙГ. ч ОБУФПСЭЕЕ ЧТЕНС РТЙОСФП ПФДЕМСФШ ДЙЪБКО ПФ РТПЗТБННОПЗП ЛПДБ. оБРТЙНЕТ, Ч УМХЮБЕ ЙУРПМШЪПЧБОЙС Perl, ПДОПЗП ЙЪ УБНЩИ ТБУРТПУФТБОЕООЩИ СЪЩЛПЧ web-РТПЗТБННЙТПЧБОЙС, ДЕМП УЧПДЙФУС Л ЗЕОЕТБГЙЙ УФТБОЙГ У РПНПЭША CGI-УЛТЙРФПЧ, РТЙЮЕН УБН HTML-ЛПД ОБИПДЙМУС Ч ПФДЕМШОЩИ ЖБКМБИ-ЫБВМПОБИ, УПУФПСЭЙИ ЙЪ ОБВПТБ ФЕЗПЧ, РЕТЕНЕООЩИ Й ХРТБЧМСАЭЙИ ПРЕТБФПТПЧ. дБООЩЕ, РПМХЮЕООЩЕ Ч ТЕЪХМШФБФЕ ТБВПФЩ УЛТЙРФПЧ, РЕТЕДБАФУС ЫБВМПОХ, ЛПФПТЩК РПДУФБЧМСЕФ ЙИ ЧНЕУФП РЕТЕНЕООЩИ. уХЭЕУФЧХЕФ ПЗТПНОПЕ ЛПМЙЮЕУФЧП НПДХМЕК, ХНЕАЭЙИ ТБВПФБФШ У ЫБВМПОБНЙ. оЕЛПФПТЩЕ ЙЪ ОЙИ РПЪЧПМСАФ ЧЛМАЮБФШ ЛПД Perl, ОЕЛПФПТЩЕ ЙУРПМШЪХАФ УЧПК СЪЩЛ РТПЗТБННЙТПЧБОЙС. рПДТПВОЕЕ П РТЙНЕОЕОЙЙ ТБЪМЙЮОЩИ НПДХМЕК НПЦОП ХЪОБФШ ЙЪ УФБФШЙ . оЕПВИПДЙНПУФШ ЛБЦДЩК ТБЪ ЪБЗТХЦБФШ ЙОФЕТРТЕФБФПТ тerl, ДПРПМОЙФЕМШОЩЕ НПДХМЙ, ПВТБВБФЩЧБФШ ЫБВМПООЩЕ ЖБКМЩ УХЭЕУФЧЕООП ОБЗТХЦБЕФ web-УЕТЧЕТ. рТЙ ВПМШЫПК РПРХМСТОПУФЙ ТЕУХТУБ ЬФП НПЦЕФ РТЙЧЕУФЙ Л ЪБНЕФОПНХ ЪБНЕДМЕОЙА ТБВПФЩ. пРЙУБООЩИ ОЕДПУФБФЛПЧ МЙЫЕО НПДХМШ mod_perl ДМС Apache. л ПУОПЧОЩН ДПУФПЙОУФЧБН mod_perl ПФОПУСФУС: * РТЙЧСЪЛБ ЙОФЕТРТЕФБФПТБ Perl Л ЛБЦДПНХ РТПГЕУУХ Apache; * API Л Apache: * ЧПЪНПЦОПУФШ ОБРЙУБОЙС УПВУФЧЕООЩИ ПВТБВПФЮЙЛПЧ УФБДЙК ЧЩРПМОЕОЙС ЪБРТПУБ – ИЬОДМЕТПЧ (handlers); * ЧПЪНПЦОПУФШ ЛПОЖЙЗХТЙТПЧБОЙС Apache; * ЛЬЫЙТПЧБОЙЕ Perl-НПДХМЕК. чЩВПТ НПДХМС нПДХМШ-ЫБВМПОЙЪБФПТ, ТБВПФБАЭЙК РПД mod_perl, СЧМСЕФУС НПЭОЩН "ДЧЙЦЛПН" ДМС УБКФПЧ МАВПК УМПЦОПУФЙ. дМС ФПЗП ЮФПВЩ ПО УФБМ ПВТБВПФЮЙЛПН УФБДЙЙ ЪБРТПУБ, ПФЧЕЮБАЭЕК ЪБ ЗЕОЕТБГЙА ЛПОФЕОФБ УФТБОЙГЩ, ОЕПВИПДЙНП ПРТЕДЕМЙФШ ЕЗП Ч ОБУФТПКЛБИ Apache ЛБЛ PerlHandler. ьФП РПЪЧПМЙФ УДЕМБФШ ЫБВМПОЩ (ДБМЕЕ ЛПНРПОЕОФЩ) ЪБРХУЛБАЭЙНЙУС, Б УБН ПВТБВПФЮЙЛ ВХДЕФ ЧЩЪЩЧБФШУС ОЕЪБНЕФОП (РП БОБМПЗЙЙ У PHP, JSP Й ASP) РТЙ ЛБЦДПН ПВТБЭЕОЙЙ Л web-УЕТЧЕТХ. чЩВПТ БЧФПТБ РБМ ОБ HTML::Mason. еЗП ЧПЪНПЦОПУФЙ ДПЧПМШОП ЫЙТПЛЙ, ПО РПЪЧПМСЕФ УНЕЫЙЧБФШ ЛПД Perl У HTML Й ЧОПУЙФШ ЙЪНЕОЕОЙС Ч ПВТБВПФЮЙЛ, Б ФБЛЦЕ РТЕЛТБУОП ЙОФЕЗТЙТХЕФУС У mod_perl. йДЕС ОБРЙУБОЙС ЧУЕЗП ЛПДБ УБКФБ ЧРЕТЕНЕЫЛХ У HTML ФБЛЦЕ ЙНЕЕФ ТСД ОЕДПУФБФЛПЧ. Mason РПЪЧПМСЕФ ДПУФЙЮШ ЛПНРТПНЙУУБ, РТЕДПУФБЧМСС ЧПЪНПЦОПУФШ ИТБОЕОЙС ПУОПЧОПЗП ЛПДБ Ч НПДХМСИ (ЛМБУУБИ). рТЙ ЬФПН ХРТПЭБЕФУС УПРТПЧПЦДЕОЙЕ РТПЕЛФБ, Б ЙУРПМШЪПЧБОЙЕ ппр ВМБЗПРТЙСФОП УЛБЪЩЧБЕФУС ОБ НБУЫФБВЙТХЕНПУФЙ. еЭЕ ПДЙО РМАУ ФБЛПК ПТЗБОЙЪБГЙЙ - ЧПЪНПЦОПУФШ НОПЗПЛТБФОПЗП РТЙНЕОЕОЙС ЛПДБ Ч МАВЩИ РТПЕЛФБИ ОБ Perl, Ч ФПН ЮЙУМЕ ЙУРПМШЪХАЭЙИ ЙОФЕТЖЕКУ CGI. дБМЕЕ Ч УФБФШЕ ВХДХФ ТБУУНПФТЕОЩ ПУОПЧОЩЕ ЧПЪНПЦОПУФЙ HTML::Mason Й РТЙЧЕДЕО РТЙНЕТ ОЕВПМШЫПЗП УБКФБ, УПЪДБООПЗП ОБ ЬФПН "ДЧЙЦЛЕ". хУФБОПЧЛБ HTML::Mason чЪСФШ НПДХМШ НПЦОП У CPAN ЙМЙ У www.masonhq.com. мАВПК ЦЕМБАЭЙК НПЦЕФ РПХЮБУФЧПЧБФШ Ч ТБЪТБВПФЛЕ Й РТЕДМПЦЙФШ УЧПК ЧБТЙБОФ ДПРПМОЕОЙК. рТПГЕУУ ХУФБОПЧЛЙ БОБМПЗЙЮЕО ПВЩЮОЩН НПДХМСН. рПЬФПНХ РЕТЕКДЕН Л ОБУФТПКЛЕ ЖБКМБ ЛПОЖЙЗХТБГЙЙ Apache. бЧФПТ ЙУРПМШЪПЧБМ ПРЕТБГЙПООХА УЙУФЕНХ FreeBSD, РПЬФПНХ РТЙЧЕДЕООЩЕ РТЙНЕТЩ РХФЕК Л ЖБКМБН ИБТБЛФЕТОЩ ЙНЕООП ДМС UNIX-УЙУФЕН. рЕТЧПЕ, ЮФП ОХЦОП УДЕМБФШ - ДПВБЧЙФШ УФТПЮЛХ: PerlModule HTML::Mason::ApacheHandler ьФП МХЮЫЕ УДЕМБФШ Ч httpd.conf, Б ОЕ Ч.htaccess, ФБЛ ЛБЛ Ч ЬФПН УМХЮБЕ ЪБЗТХЪЛБ НПДХМС РТПЙЪПКДЕФ РТЙ ЪБРХУЛЕ web-УЕТЧЕТБ, Ч ПУОПЧОПН РТПГЕУУЕ Apache, Б ЧУЕ РПТПЦДЕООЩЕ РТПГЕУУЩ ВХДХФ ЙУРПМШЪПЧБФШ ТБЪДЕМСЕНХА РБНСФШ. ьФП РПЪЧПМЙФ ВПМЕЕ ЬЛПОПНОП ТБУИПДПЧБФШ РБНСФШ (Mason - ОЕ УБНЩК НБМЕОШЛЙК НПДХМШ), Б ФБЛЦЕ УХЭЕУФЧЕООП УПЛТБФЙФШ ЧТЕНС ЪБЗТХЪЛЙ ЛПНРПОЕОФБ РТЙ РЕТЧПН ПВТБЭЕОЙЙ. ч РТПФЙЧОПН УМХЮБЕ Mason ВХДЕФ ЪБЗТХЦБФШУС ЛБЦДЩН РТПГЕУУПН ПФДЕМШОП. дБМЕЕ УМЕДХЕФ ДПВБЧЙФШ Ч ЛПОЖЙЗХТБГЙПООЩК ЖБКМ ДЧЕ РЕТЕНЕООЩЕ: PerlSetVar MasonCompRoot /usr/local/www/data PerlSetVar MasonDataDir /usr/local/www/mason рЕТЧБС РЕТЕНЕООБС ПРТЕДЕМСЕФ ЛПТОЕЧХА ДЙТЕЛФПТЙА ЛПНРПОЕОФПЧ. чФПТБС - ДЙТЕЛФПТЙА ТБЪНЕЭЕОЙС УМХЦЕВОЩИ ЖБКМПЧ. рТЙ РЕТЧПН ЪБРХУЛЕ Mason УПЪДБЕФ ФБН ОЕУЛПМШЛП ДЙТЕЛФПТЙК. уАДБ УЛМБДЩЧБАФУС ФБЛЦЕ РТЕПВТБЪПЧБООЩЕ ЛПНРПОЕОФЩ Й ЛЬЫЙТПЧБООЩЕ ДБООЩЕ. фЕРЕТШ ПУФБМПУШ РТПРЙУБФШ ИЬОДМЕТ. дПЗПЧПТЙНУС, ЮФП ТБУЫЙТЕОЙЕ ЛПНРПОЕОФПЧ ВХДЕФ ЙНЕООП.html. оБУФТПЙН Apache ФБЛЙН ПВТБЪПН, ЮФПВЩ ЖБКМЩ, ПФМЙЮОЩЕ ПФ *.html, *.txt Й ЖБКМПЧ ВЕЪ ТБУЫЙТЕОЙК, ОЕ ПВТБВБФЩЧБМЙУШ HTML::Mason: SetHandler perl-script PerlHandler HTML::Mason пУОПЧЩ "ДЧЙЦЛБ" Mason лБЛ ХЦЕ ВЩМП УЛБЪБОП, Mason РПЪЧПМСЕФ ЧУФТБЙЧБФШ Perl-ЛПД Ч УБН ДПЛХНЕОФ. ьФП НПЦОП УДЕМБФШ ОЕУЛПМШЛЙНЙ УРПУПВБНЙ, ЛБЦДЩК ЙЪ ЛПФПТЩИ ХДПВЕО Ч ТБЪОЩИ УЙФХБГЙСИ. фБЛ ЛБЛ ЪОБЮЕОЙС ЗМПВБМШОЩИ РЕТЕНЕООЩИ ОЕ ХОЙЮФПЦБАФУС РПУМЕ ЪБЧЕТЫЕОЙС РТПЗТБННЩ (ПУПВЕООПУФШ mod_perl), ФП ЧУЕ ЙУРПМШЪХЕНЩЕ РЕТЕНЕООЩЕ ОЕПВИПДЙНП ПВЯСЧМСФШ ЛБЛ МЕЛУЙЮЕУЛЙЕ, ЪБ ЙУЛМАЮЕОЙЕН ПРТЕДЕМЕООЩИ УМХЮБЕЧ, П ЛПФПТЩИ ВХДЕФ ТБУУЛБЪБОП РПЪЦЕ. ч РТПФЙЧОПН УМХЮБЕ ЛПНРПОЕОФ Mason ОЕ РТПКДЕФ ЛПНРЙМСГЙА, ФБЛ ЛБЛ ЧЕУШ ЛПД РТПЧЕТСЕФУС РТБЗНПК strict. фЕРЕТШ ПВ ПУОПЧБИ УЙОФБЛУЙУБ Mason. 1. уФТПЛБ, ОБЮЙОБАЭБСУС У УЙНЧПМБ %, ЧПУРТЙОЙНБЕФУС, ЛБЛ Perl-ЛПД. ьФБ ЛПОУФТХЛГЙС ПЮЕОШ ХДПВОБ Ч ХРТБЧМСАЭЙИ ПРЕТБФПТБИ. рТЙНЕТ: % if ($browser =~ /msie/i) {

чЩ ЙУРПМШЪХЕФЕ Internet Explorer

% } else {

х ЧБУ, УЛПТЕЕ ЧУЕЗП, Netscape

% } нЙОЙНХН УЙОФБЛУЙУБ, НБЛУЙНХН ХДПВУФЧБ. 2. вМПЛ <% EXPR %> ЪБНЕОСЕФУС ТЕЪХМШФБФПН ЧЩЮЙУМЕОЙС ЧЩТБЦЕОЙС EXPR. пВЩЮОП РТЙНЕОСЕФУС ДМС ЧЩЧПДБ РЕТЕНЕООЩИ. рТЙНЕТ: Hello, <% $name %> <% ($name ? "Hello, $name" : "") %> ч ВМПЛЕ РТЕДХУНПФТЕОБ ЧПЪНПЦОПУФШ ЖПТНБФЙТПЧБОЙС ТЕЪХМШФБФБ: <% $html_tags |h %> - ЪБНЕОСЕФ ЧУЕ "<" ОБ "<" Й Ф.Д. <% $string |u %> - РТЕПВТБЪПЧЩЧБЕФ УФТПЛХ Ч urlencoded (РТЙНЕТ: ":" ЪБНЕОСЕФУС ОБ "%3A") 3. вПМШЫЙЕ Perl-ВМПЛЙ НПЦОП ЧУФБЧМСФШ НЕЦДХ ФЕЗБНЙ <%perl> ... 4. ч ЛПНРПОЕОФБИ ДПУФХРОЩ ДЧБ ЗМПВБМШОЩИ ПВЯЕЛФБ. рЕТЧЩК - $r, ПВЯЕЛФ НПДХМС Apache, ЙЪ ОЕЗП НПЦОП ЧЩЪЩЧБФШ ЧУЕ НЕФПДЩ ЬФПЗП НПДХМС, ЧФПТПК - $m, ПВЯЕЛФ Mason. пВЯЕЛФ $m, ПВЕУРЕЮЙЧБЕФ ДПУФХР Л ПЮЕОШ РПМЕЪОЩН НЕФПДБН, РПМОПЕ ПРЙУБОЙЕ ЛПФПТЩИ НПЦОП ОБКФЙ Ч ДПЛХНЕОФБГЙЙ Л Mason (perldoc HTML::Mason::Request). рТЙНЕТ ЙУРПМШЪПЧБОЙС ПВЯЕЛФБ $r: % my $ua = $r->header_in("User-Agent"); % my $host = $r->get_remote_host; 5. Mason ОЕ ВЩМ ВЩ ФБЛ РПРХМСТЕО, ЕУМЙ ВЩ Ч ОЕН ОЕМШЪС ВЩМП РПДЛМАЮБФШ ДТХЗЙЕ ЛПНРПОЕОФЩ. уМПЦОЩК ДПЛХНЕОФ ВЩЧБЕФ ХДПВОП ТБЪВЙФШ ОБ ОЕУЛПМШЛП ЖБКМПЧ. пДЙОБЛПЧЩЕ ЛПНРПОЕОФЩ НПЦОП ЙУРПМШЪПЧБФШ Ч ТБЪОЩИ УФТБОЙГБИ, РЕТЕДБЧБС ЙН УППФЧЕФУФЧХАЭЙЕ РБТБНЕФТЩ. еУФШ ДЧБ УРПУПВБ ЧЩЪПЧБ ЛПНРПОЕОФПЧ. рЕТЧЩК РТЕДОБЪОБЮЕО ДМС ЧУФБЧЛЙ Ч HTML, ЧФПТПК РТЕДУФБЧМСЕФ УПВПК НЕФПД ПВЯЕЛФБ $m. рТЙНЕТ: 1) <& /path/comp_name, par1 => $value1, par2 => $value2 &> 2) $m->comp("/path/comp_name",par1 => $value1, par2 => $value2); рХФШ ЧЩЮЙУМСЕФУС ПФОПУЙФЕМШОП MasonCompRoot. ч ЛБЮЕУФЧЕ РБТБНЕФТПЧ НПЦОП РЕТЕДБЧБФШ УУЩМЛЙ ОБ НБУУЙЧЩ Й ИЬЫЙ. пУФБМШОЩЕ РЕТЕНЕООЩЕ Ч ЧЩЪЧБООПН ЛПНРПОЕОФЕ ОЕДПУФХРОЩ. 6. еУМЙ ЕУФШ ЧПЪНПЦОПУФШ РЕТЕДБФШ ДБООЩЕ, ДПМЦЕО ВЩФШ УРПУПВ ЙИ ЙЪЧМЕЮШ. ъДЕУШ Mason ПРСФШ РТЕДМБЗБЕФ ОЕУЛПМШЛП УРПУПВПЧ. рТЙЮЕН ОЕЧБЦОП, РЕТЕДБАФУС МЙ ЬФЙ РБТБНЕФТЩ ЮЕТЕЪ ЪБРТПУ GET (POST) ЙМЙ ЦЕ РТЙ ЧЩЪПЧЕ ЛПНРПОЕОФБ. рЕТЧЩК УРПУПВ иЬЫ %ARGS УПДЕТЦЙФ ЧУЕ РЕТЕДБООЩЕ РБТБНЕФТЩ. еУМЙ ЙНЕОБ РБТБНЕФТПЧ РПЧФПТСАФУС (ОБРТЙНЕТ, РТЙ ЙУРПМШЪПЧБОЙЙ checkbox), ФП УППФЧЕФУФЧХАЭЙК ЛМАЮ ИЬЫБ УПДЕТЦЙФ УУЩМЛХ ОБ НБУУЙЧ. у ПДОПК УФПТПОЩ, ИЬЫ ХДПВЕО ДМС ТБЪТБВПФЮЙЛБ, ПО ЧЩДЕМСЕФ РЕТЕНЕООЩЕ, Л ЛПФПТЩН ОЕПВИПДЙНП ПФОПУЙФУС У ВПМШЫПК ПУФПТПЦОПУФША, ФБЛ ЛБЛ ПОЙ РЕТЕДБАФУС ПФ РПМШЪПЧБФЕМС. у ДТХЗПК, ЪБРЙУЙ ЧЩЗМСДСФ ПЮЕОШ ЗТПНПЪДЛП. Mason РТЕДМБЗБЕФ БМШФЕТОБФЙЧОЩК ЧБТЙБОФ РПМХЮЕОЙС РБТБНЕФТПЧ. чФПТПК УРПУПВ <%args> $par1 => undef @par2 => undef ъДЕУШ ЧУЕ РПОСФОП, undef РПУМЕ => ЪБДБЕФ ЪОБЮЕОЙЕ РП ХНПМЮБОЙА, ЕУМЙ ЧП ЧИПДОЩИ ДБООЩИ РБТБНЕФТ ВХДЕФ ПФУХФУФЧПЧБФШ. рПЧФПТСАЭЙЕУС РБТБНЕФТЩ РПРБДБАФ Ч НБУУЙЧ. 7. уЕЛГЙЙ <%init> ... Й <%cleanup> ... ПРТЕДЕМСАФ ЛПД ЙОЙГЙБМЙЪБГЙЙ Й ЪБЧЕТЫЕОЙС УППФЧЕФУФЧЕООП. уПЪДБОЙЕ УБКФБ чППВЭЕ, РТПЗТБННЙТПЧБФШ ДМС Mason-ДЧЙЦЛБ ПДОП ХДПЧПМШУФЧЙЕ: ЧТЕНС ТБЪТБВПФЛЙ ТХФЙООЩИ ЧЕЭЕК УПЛТБЭБЕФУС, РПЪЧПМСС УПУТЕДПФПЮЙФУС ОБ ПУОПЧОПН РТПЗТБННЙТПЧБОЙЙ. уПЪДБОЙЕ ДЙЪБКОБ ПРХУФЙН Й РЕТЕКДЕН Л РТПЗТБННОПК ЮБУФЙ. фБЛ ЛБЛ ДЙЪБКО УБКФБ ВХДЕФ ПДЙОБЛПЧЩН ДМС ЧУЕИ УФТБОЙГ, ЧЩДЕМЙН УФБФЙЮЕУЛХА Й ДЙОБНЙЮЕУЛХА ЮБУФЙ. ч РТПУФЕКЫЕН УМХЮБЕ ЬФП ФТЙ ЬМЕНЕОФБ: ЧЕТИОСС ЮБУФШ УФТБОЙГЩ (header), ФЕМП УФТБОЙГЩ (body) Й ОЙЦОСС ЮБУФШ (footer) – УН. ТЙУ. 1. Header Й footer (УФБФЙЮЕУЛБС ЮБУФШ УБКФБ) ВХДХФ ПВЭЙНЙ ДМС ЧУЕИ УФТБОЙГ. рПЬФПНХ ЙИ НПЦОП ЧЩОЕУФЙ Ч ПФДЕМШОЩЕ ЛПНРПОЕОФЩ Й РПДЛМАЮБФШ ЧП ЧУЕИ УФТБОЙГБИ. оП РТПРЙУЩЧБФШ ПДЙО Й ФПФ ЦЕ ЛПД ЧП ЧУЕИ ЛПНРПОЕОФБИ (Ч ДЙОБНЙЮЕУЛПК ЮБУФЙ) - ЪБОСФЙЕ ОЕВМБЗПДБТОПЕ. рТПЗТБННЙУФЩ ОБ (PHP/ASP) ПВИПДСФ ЬФП ОЕХДПВУФЧП, ПТЗБОЙЪХС ЧЩЧПД ЧУЕЗП УПДЕТЦЙНПЗП УБКФБ ЙЪ ПДОПК УФТБОЙГЩ. рЕТЕДБЧБЕНЩК РБТБНЕФТ, ПРТЕДЕМСЕФ, ЛБЛПК ДПЛХНЕОФ ОХЦОП ЧЩДБФШ. оП ЬФП ОЕ УБНЩК МХЮЫЙК ЧБТЙБОФ, Й РТЙ УМПЦОПК УФТХЛФХТЕ УБКФБ РПТПЦДБЕФ ТСД РТПВМЕН. Mason РТЕДМБЗБЕФ ВПМЕЕ ХДПВОЩК УРПУПВ ПВИПДБ ДБООПЗП ОЕХДПВУФЧБ - ЮЕТЕЪ ЛПНРПОЕОФ autohandler. Mason РЕТЕД ПВТБВПФЛПК ЧЩЪЧБООПЗП ЛПНРПОЕОФБ РТПЧЕТСЕФ Ч ФЕЛХЭЕК Й ЧЩЫЕМЕЦБЭЙИ ДЙТЕЛФПТЙСИ ОБМЙЮЙЕ ЖБКМБ autohandler. еУМЙ ПО ОБКДЕО, ХРТБЧМЕОЙЕ УОБЮБМБ РЕТЕДБЕФУС ЕНХ. йФБЛ, РТЙЫМП ЧТЕНС ОБРЙУБОЙС РЕТЧПЗП Mason-ДПЛХНЕОФБ. жБКМ autohandler: @ Test page @ >
<% scalar localtime() %>
Test page
<% $m->call_next %>
<%init> my $BG; my $FN; $BG = $cookie{"BG"} || "#006633"; $FN = $cookie{"FN"} || "#cccc66"; дМС ЬЛПОПНЙЙ НЕУФБ ПРЙУБОЙС УФЙМЕК ПРХЭЕОЩ. рПМОХА ЧЕТУЙА ФЕУФПЧПЗП УБКФБ НПЦОП ЧЪСФШ РП БДТЕУХ . ч autohandler ОБИПДСФУС Й header Й footer. тБЪВЕТЕНУС, ЛБЛ ЧУЕ ТБВПФБЕФ. рХУФШ ЪБРТБЫЙЧБЕФУС ЖБКМ index.html. Mason УОБЮБМБ ОБИПДЙФ autohandler, ЧЩРПМОСЕФ ВМПЛ <%init> Й ЧЩДБЕФ РПМШЪПЧБФЕМА ЧУЕ, ЮФП РТЕДЫЕУФЧХЕФ $m->call_next. ьФП Й ЕУФШ ОБЫ header. нЕФПД call_next РЕТЕДБЕФ ХРТБЧМЕОЙЕ ЪБРТПЫЕООПНХ ЛПНРПОЕОФХ (index.html). рПУМЕ ПВТБВПФЛЙ Й ЧЩДБЮЙ ТЕЪХМШФБФПЧ ТБВПФЩ index.html ЧЩЧПДЙФУС ПУФБЧЫБСУС ЮБУФШ autohandler. уФТЕНСУШ УДЕМБФШ УБКФ НБЛУЙНБМШОП ХДПВОЩН, РТЕДПУФБЧЙН РПУЕФЙФЕМА ЧПЪНПЦОПУФШ ОБУФТБЙЧБФШ ГЧЕФ ФЕЛУФБ Й ЖПОБ (ИПФС РБТБНЕФТПЧ НПЦОП ЧЩВТБФШ ВПМШЫЕ, ОП ДМС ДЕНПОУФТБГЙЙ ПЗТБОЙЮЙНУС ДЧХНС). чЩ, ОБЧЕТОПЕ, ЪБНЕФЙМЙ ЗМПВБМШОЩК ИЬЫ %cookie. ьФПФ ИЬЫ УПДЕТЦЙФ РЕТЕДБООЩЕ ВТБХЪЕТПН cookies. рПЛБ ОЕ ВХДЕН ЧДБЧБФШУС Ч РПДТПВОПУФЙ ЪБОЕУЕОЙС cookies Ч ЬФПФ ИЬЫ. фБЛЙН ПВТБЪПН, ЕУМЙ ПФ РПМШЪПЧБФЕМС РПУЩМБАФУС cookies, ФП ЪОБЮЕОЙС РП ХНПМЮБОЙА ЪБНЕОСАФУС РПМШЪПЧБФЕМШУЛЙНЙ. вМБЗПДБТС autohandler, ОБУ ВПМШЫЕ ОЕ ВХДЕФ ВЕУРПЛПЙФШ ЗПМПЧОБС ВПМШ РП ХЮЕФХ ЛМЙЕОФУЛЙИ ОБУФТПЕЛ Й ЧЩЧПДХ УФБФЙЮЕУЛПК ЮБУФЙ УБКФБ. фЕРЕТШ НПЦОП УПУТЕДПФПЮЙФШУС ОБ РТПЗТБННЙТПЧБОЙЙ ВПМЕЕ ЧБЦОЩИ ЧЕЭЕК. дБМЕЕ ТБУУНПФТЙН ЖБКМ index.html (ТЙУ. 2). дПРХУФЙН, ПО ЧЩЧПДЙФ РПУМЕДОЙЕ 10 ОПЧПУФЕК, УПТФЙТХС РП ХВЩЧБОЙА ДБФ. чУЕ ОПЧПУФЙ ИТБОСФУС Ч MySQL Ч ФБВМЙГЕ news. % while (my ($date,$desrc,$link) = $select->fetchrow()) { % }
<% $date %> - <% $descr %> ...">рПДТПВОЕЕ
<%init> my $select = $dbh->prepare(qq(SELECT * FROM news ORDER BY ndate DESC LIMIT 10)); $select->execute; <%cleanup> $select->finish; бЧФПТ ОЕ УФПТПООЙЛ ФПЗП, ЮФПВЩ ИТБОЙФШ SQL-ЛПД Ч ЛПНРПОЕОФБИ. рТЙ ЙЪНЕОЕОЙЙ ФБВМЙГЩ НПЦОП РТПУФП ОЕ ЧУРПНОЙФШ, Ч ЛБЛЙИ ДПЛХНЕОФБИ ПУХЭЕУФЧМСЕФУС ЧЩВПТЛБ. пРФЙНБМШОЩН ЧБТЙБОФПН НПЦЕФ ВЩФШ УПЪДБОЙЕ ПФДЕМШОПЗП НПДХМС У ЛПОУФБОФБНЙ ЙМЙ ЙУРПМШЪПЧБОЙЕ УПВУФЧЕООЩИ РТПГЕДХТ. ч ОБЮБМЕ УФБФШЙ ЗПЧПТЙМПУШ, ЮФП НПДХМШ Mason РПЪЧПМСЕФ ЧОПУЙФШ ЙЪНЕОЕОЙС Ч ПВТБВПФЮЙЛ, Б ФПЮОЕЕ ЙУРПМШЪПЧБФШ УЧПК. еУМЙ ЕУФШ ЧПЪНПЦОПУФШ, МХЮЫЕ ЙУРПМШЪПЧБФШ ЙНЕООП ЕЗП. ч ДЙУФТЙВХФЙЧЕ НПДХМС ЕУФШ "УЛЕМЕФ" ЬФПЗП ПВТБВПФЮЙЛБ - ЖБКМ handler.pl. лПОЕЮОП ЦЕ, ЧБН ОЕ РТЙДЕФУС РЙУБФШ У ОХМС УЧПК handler. дПУФБФПЮОП МЙЫШ ДПРЙУБФШ УЧПК ЛПД Ч ХЦЕ ЙНЕАЭЙКУС. ч handler.pl РПДЛМАЮБЕФУС HTML::Mason, ПО-ФП Й ЧЩРПМОСЕФ ЧУА ТБВПФХ. ч ЬФПН ЖБКМЕ УПЪДБАФУС ЗМПВБМШОЩЕ ИЬЫ %cookie Й ПВЯЕЛФ $dbh. оЕ ЪБВХДШФЕ ЪБНЕОЙФШ УФТПЛХ PerlModule HTML::Mason::ApacheHandler ОБ PerlRequire /path/handler.pl Ч httpd.conf. ч handler.pl ЕУФШ ДЧБ ВМПЛБ, Ч ЛПФПТЩЕ НПЦОП ЧОПУЙФШ ЙЪНЕОЕОЙС. ч РЕТЧПН РПДЛМАЮБАФУС НПДХМЙ. пЮЕОШ ХДПВОП РПДЛМАЮБФШ Ч ЬФПН ВМПЛЕ ЧУЕ ЙУРПМШЪХЕНЩЕ НПДХМЙ Й ТБВПФБФШ У ОЙНЙ Ч ЛПНРПОЕОФБИ ЮЕТЕЪ ЗМПВБМШОЩЕ ПВЯЕЛФЩ. чП ЧФПТПН (НЕФПД handler) ПРЙУЩЧБЕФУС ЧЕУШ ЛПД. рТЙНЕТ ЖБКМБ handler.pl: package HTML::Mason; use HTML::Mason; use HTML::Mason::ApacheHandler; use strict; { # ВМПЛ РПДЛМАЮЕОЙС НПДХМЕК package HTML::Mason::Commands; # ЗМПВБМШОЩЕ РЕТЕНЕООЩЕ use vars qw(%cookie $dbh); # ЙУРПМШЪХЕНЩЕ НПДХМЙ use CGI::Cookie; use DBI; } # УПЪДБОЙЕ ПВЯЕЛФПЧ mason my $parser = new HTML::Mason::Parser; my $interp = new HTML::Mason::Interp (parser => $parser, comp_root => "/usr/local/www/mason", data_dir => "/usr/local/www/data"); my $ah = new HTML::Mason::ApacheHandler (interp => $interp); chown (Apache->server->uid, Apache->server->gid, $interp->files_written); sub handler { my ($r) = @_; my %c = parse CGI::Cookie($r->header_in("Cookie")); # ХДБМСЕН РТЕДЯЩДХЭЕЕ ЪОБЮЕОЙЕ %HTML::Mason::Commands::cookie = (); foreach my $temp (keys %c) { # ДПВБЧМСЕН ЪОБЮЕОЙС Ч ИЬЫ $HTML::Mason::Commands::cookie{$temp} = $c{$temp}->value(); } # РПДЛМАЮБЕНУС Л вд $HTML::Mason::Commands::dbh = DBI->connect("DBI:mysql:database=mason;host=host", "user","pass"); my $status = $ah->handle_request($r); $HTML::Mason::Commands::dbh->disconnect(); return $status; } лПНРПОЕОФ У ЖПТНПК ОБУФТПКЛЙ ДЙЪБКОБ УБКФБ ЧЩЗМСДЙФ УМЕДХАЭЙН ПВТБЪПН. <%def .outmesg> <% $ARGS{"MESG"}%> оБУФТПКЛБ УБКФБ
гЧЕФ ЖПОБ: гЧЕФ ЫТЙЖФБ:
<%init> if ($ARGS{"GO"}) { # РТПЧЕТЛБ ЧЧЕДЕООЩИ РПМЕК if ($ARGS{"BG"} !~ /^[\d\w]+$/ || $ARGS{"FN"} !~ /^[\d\w]+$/) { $m->comp(".outmesg", MESG => "оЕРТБЧЙМШОП ЧЧЕДЕОЩ ДБООЩЕ"); } else { $r->headers_out->add("Set-Cookie","BG=$ARGS{"BG"}"); $r->headers_out->add("Set-Cookie","FN=$ARGS{"FN"}"); $m->comp(".outmesg",MESG => "хУФБОПЧЛЙ УПИТБОЕОЩ"); } } фЕЗ <%def> ПРЙУЩЧБЕФ ЛПНРПОЕОФ Ч ЛПНРПОЕОФЕ. рПУМЕДОЙЕ ЫФТЙИЙ дМС ФПЗП, ЮФПВЩ ЙУЛМАЮЙФШ ЧПЪНПЦОПУФШ ЧЩЪПЧБ ЧОХФТЕООЙИ ЛПНРПОЕОФ, ОХЦОП ДПВБЧЙФШ Ч ЛПОЖЙЗХТБГЙПООЩК ЖБКМ УФТПЛЙ: PerlModule Apache::Constants SetHandler perl-script PerlInitHandler Apache::Constants::NOT_FOUND ьФП ЪБЭЙФЙФ ЧОХФТЕООЙЕ ЛПНРПОЕОФЩ ПФ ОЕЦЕМБФЕМШОПЗП ЧЩЪПЧБ ЙЪ ВТБХЪЕТБ. оП Ч ЬФПН УМХЮБЕ ЧУЕ ЧОХФТЕООЙЕ ЛПНРПОЕОФЩ ДПМЦОЩ ОБЮЙОБФШУС У УЙНЧПМБ “_”. ъБЛМАЮЕОЙЕ вПМЕЕ РПДТПВОХА ЙОЖПТНБГЙА НПЦОП ХЪОБФШ ЙЪ ДПЛХНЕОФБГЙЙ Л НПДХМА (perldoc HTML::Mason::Devel, perldoc HTML::Mason::Admin). п HTML::Mason Ч УФБФШЕ УЛБЪБОП ДБМЕЛП ОЕ ЧУЕ. оП РТЙЧЕДЕООПК ЙОЖПТНБГЙЙ ХЦЕ ДПУФБФПЮОП ДМС ФПЗП, ЮФПВЩ ПГЕОЙФШ ДПУФПЙОУФЧБ ЬФПЗП НПДХМС. уФБТБОЙС ТБЪТБВПФЮЙЛПЧ ОЕ РТПЫМЙ ДБТПН. ьФПФ НПДХМШ ХЦЕ ХУРЕМ ЪБОСФШ ДБМЕЛП ОЕ УБНПЕ РПУМЕДОЕЕ НЕУФП Ч УРЙУЛЕ РПРХМСТОЩИ web-ФЕИОПМПЗЙК. уУЩМЛЙ 1. тЕУХТУЩ РП mod_perl Й ЫБВМПОБН

Наташа 30 июня 2012 в 14:04

Ввод-вывод в Perl

  • Чулан *

Здравствуйте!

Начав читать книгу «Шварц Р., Фой Б., Феникс Т. - Perl. Изучаем глубже. 2-е издание», понял, что немного запутался в способах ввода-вывода Perl. Для этого решил сделать вот-такой конспект, который хочу предложить вашему вниманию.

Работа с аргументами вызова скрипта
Аргументы вызова скрипта заносятся в массив @ARGV, т.е. для следующего вызова

$ perl test.pl lesson1 lesson2 lesson3

Массив @ARGV будет содержать qw/lesson1 lesson2 lesson3/.

Работа с массивом @ARGV как с переменной по-умолчанию
С массивом @ARGV можно работать как с переменной по-умолчанию (аналогично $_ или @_).

My $line = shift; my $line = shift @ARGV; my $line = pop; my $line = pop @ARGV;

Эти две пары строк эквивалентны, за одним исключением - версии с аргументом по-умолчанию не должны вызываться внутри подпрограммы, т.к. там имеется своя переменная по-умолчанию - @_. Приведем пример:

Use Modern::Perl; use utf8; my $arg1 = shift; # по-умолчанию используется массив @ARGV say «arg1: $arg1»; my @name_and_arg = get_name_and_arg(„TheAthlete”); say «(name arg2) = (@name_and_arg)»; sub get_name_and_arg { my $name = shift; # по-умолчанию используется массив @_ my $arg2 = shift @ARGV; # явно используем @ARGV return ($name, $arg2); }

$ perl test.pl hello world
arg1: hello
(name arg2) = (TheAthlete world)
$

На самом деле операция pop выполняется довольно редко.

Чтение данных из стандартного ввода
Получить данные из стандартного потока ввода можно с помощью оператора . Выполнение этого оператора в скалярном контексте дает следующую строку данных:

; # Прочитать следующую строку chomp $name; # Удалить завершитель say «Name: $name»;

$ perl test.pl
Enter name: Fred
Name: Fred
$

При достижении конца файла (в данном примере это ввод Ctrl+d в Linux или Ctrl+z в Windows вместо ввода имени) оператор построчного вывода возвращает undef. Чтобы было более понятно, этот пример можно переписать следующим способом:

Print «Enter name: »; my $name = ; # Прочитать следующую строку if (defined $name) { chomp $name; # Удалить завершитель say «Name: $name»; } else { say «Пустая строка ввода»; }

$ perl test.pl
Enter name: или
Пустая строка ввода
$

Также, это обстоятельство часто используется для выхода из цикла:

My $name; print «Enter name: »; while (defined($name = )) { chomp $name; say «Name: $name»; }

$ perl test.pl
Enter name: Vasya
Name: Vasya
Petya
Name: Petya
Kolya
Name: Kolya
или
$

Для такой простой ситуации, как эта, есть сокращенная версия:

Print «Enter name: »; while () { chomp; say «Name: $_»; }

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

Оператор построчного ввода может работать также в списочном контексте:

My @names; print «Enter names: » chomp(@names = ); say «names: @names»;

$ perl test.pl
Enter names: Fred
Wilma
Kolya
Sanya
names: Fred Wilma Kolya Sanya

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

Test1.txt
test1 text

Test2.txt
test2 text

Test3.txt
test3 text

Test.pl
use Modern::Perl; use utf8; my $line; while (defined($line = <>)) { chomp $line; say $line; }

$ perl test.pl test1.txt test2.txt test3.txt
test1 text
test2 text
test3 text

Как и в случае с оператором построчного ввода, данную программу можно существенно сократить:

Use Modern::Perl; use utf8; while (<>) {chomp; say;}

Данная программа последовательно проходит каждую строку в каждом файле. При использовании оператора <> все выглядит так, словно входные файлы объединены в один большой файл. Оператор <> возвращает undef (что приводит к выходу из цикла while) только в конце всех входных данных.

Получение списка файлов по шаблону.
Если требуется получить список файлов по шаблону, аналогичному конструкциям *.* (MS-DOS, Windows) и *.h (UNIX), то можно воспользоваться следующей записью:

My @list = <*.c>; my @list = glob(„*.c”);

Также оператор <> может применяться к файловым дескрипторам, но в этой статье я не буду освещать данную тему.

Теги: perl, ввод-вывод