CGI: от printf("<head>") до XML
введениеПосле написания статьи об XML и получения отзывов типа "мне вообще ничего не понятно", мне пришла мысль написать более последовательно, то есть начать с самого начала.
Описанное в предыдущей статье затрагивает огромное количество технологий и является следствием многолетнего опыта разработчиков во всем мире. Поэтому статья и ДОЛЖНА быть непонятна людям, не прошедшим до конца через мясорубку CGI-программирования.
Скажу сразу, что я сторонник концепции HTML-шаблонов, и в этой статье попытаюсь объективно рассказать о данном подходе на примере использования перловых модулей HTML::Template и XML::Sablotron. "Объективно" означает, что я всего лишь рассказываю о собственном скудном опыте и постараюсь описать все преимущества и недостатки метода, с которыми мне УЖЕ удалось столкнуться.
Также замечу, что я знаю очень мало:
- я не читал оригинального описания CGI,
- я не писал на PHP, ASP, ColdFusion, Embedded Perl, Python
- в моих проектах был сильный перекос от дизайна в сторону программирования
- я на сделал ни одного проекта с XML
Так что если кто нибудь покажет лучший способ создания динамических веб-страниц (для этого есть гостевая, форум, почта и ICQ), я с радостью перейду на его сторону.
1. Что такое CGICGI был задуман как механизм встраивания пользовательских программ в веб-сервер. Цель - взаимодействие сервера с пользователем посредством обработки HTML-форм.
Я думаю, что спецификация CGI включает в себя
- способ передачи параметров формы из веб-страницы на сервер
- способ запуска обработчика формы (скрипта) веб-сервером
- способ передачи параметров формы от веб-сервера скрипту
- способ передачи параметров соединения и настроек веб-сервера скрипту
- способ передачи сформированной веб-страницы от скрипта веб-серверу
Так как многие из этих пунктов сохранились в почти неизменном виде до настоящего времени, под CGI-программированием я понимаю написание ЛЮБЫХ серверных скриптов. Новые механизмы вроде ISAPI и модулей Apache затронули в основном производительность, суть же осталась такой же уродливой, какой она была в самом начале. Основная причина - протокол HTTP не предназначен для того, для чего его сейчас используют.
2. HTML внутри кодаВот вам cразу пример CGI-скрипта на Си:
#include <stdio.h>
int main()
{
puts("Content-type: text/html\n");
puts("<html>");
puts("<head></head>");
printf("<body>Hello, world!</body>");
puts("</html>");
return(0);
}
Я выбрал Си потому, что на нем ясно видна "простынность" метода. То есть большую часть исходного текста занимают "простыни" из строк HTML-кода, обрамленные кавычками и другими элементами языка программирования. Многие языки, например, Перл, умеют элегантно работать с многострочными вставками, но суть остается той же:
#!/usr/bin/perl
print <<'END_MARKER';
Content-type:text/html
<html>
<head></head>
<body>Hello, world!</body>
END_MARKER
exit 0;Вот более правдоподобный пример (скрипт, суммирующий 2 числа, введенные пользователем в форме):
#!/usr/bin/perl
use CGI;
$q = new CGI;
$q->import_names('Q');
print <<'END_MARKER1';
Content-type:text/html
<html>
<head></head>
<body>Hello, world!<br>
<table>
<tr>
<th>a</th>b<th></th><th>a + b</th>
</tr>
<tr>
END_MARKER1
$c = $Q::a + $Q::b;
print "<td>$Q::a</td><td>$Q::b</td><td>$c</td>";
print <<print 'END_MARKER2';
</tr>
</table>
</body>
END_MARKER2
exit 0;
Видны два фрагмента HTML, окруженных похожими строками кода. Это "пролог" и "эпилог", содержащие части страницы до и после динамической части. Более того, динамическая часть занимает лишь малую часть кода, но в результате первоначальная структура HTML полностью исковеркана, и трудно вносить какие-либо изменения в дизайн. Бороться с этим был призван метод, о котором читайте в главе 3.
3. Код внутри HTMLЕсли в коде страницы оказывается HTML значительно больше, чем языка программирования, то почему бы не включить фрагменты программы в HTML вместо того, чтобы включать HTML в программу? Этот подход был реализован создателями ASP, PHP, Embedded Perl и, в довольно интересном виде, создателями Cold Fusion:
Скрипт на PHP:
<html>
<head></head>
<body>Hello, world!<br>
<table border=1>
<tr>
<th>A</th><th>B</th><th>A + B</th>
</tr>
<tr>
<td><? echo $A ?></td>
<td><? echo $B ?></td>
<td><? echo $A + $B ?></td>
</td>
</tr>
</table>
</body>
</html>
Скрипт на Сold Fusion:
<html>
<head></head>
<body>Hello, world!<br>
<table border=1>
<tr>
<th>A</th><th>B</th><th>A + B</th>
</tr>
<tr>
<td colspan=3>
<!-- Помогите написать!
CFML - очень интересный язык! -->
</td>
</tr>
</table>
</body>
</html>
Сразу видно преимущество PHP и CFML - код стал значительно меньше, читабельней, стало легче модифицировать HTML. Однако в реальных проектах все значительно сложнее: и кода, и HTML намного больше. Появляются ситуации, мешающие подобному стилю написания либо вообще делающие его непригодным. Вот пример:
...
Часто разработчики идут вразрез с первоначальной концепцией PHP и вставляют HTML внутрь кода,
и получается некое подобие первоначального примера на Си:
...
По мере усложнения кода становится все труднее его модифицировать и даже понимать. Наличие синтаксически чуждого HTML усугубляет положение. Становится очевидной необходимость разделения HTML и кода для того, чтобы их можно было легко поддерживать и обновлять по отдельности. Появляeтся cледующий алгоритм решения - вынесение пролога и эпилога в отдельные файлы
<? include "common.inc" ?>
<? include "header.inc" ?>
<?
// код инициализации БД и выполнения запроса
while () # цикл по строкам т-цы
{
$a = ...
?>
<tr>
<td><? echo $a ?></td>
</tr>
<?
}
?>
<? include "footer.inc ">
При этом упрощается работа с кодом, но усложняется работа с HTML. Например, очень трудно контролировать соответствие открывающего тега в прологе закрывающему тегу в эпилоге. Значит, целостность HTML нарушать нежелательно, и нужно выносить код за пределы HTML-файла. Но полностью вынести код, естественно, не удается:
<? include code.inc // код, заполняющий структуры данных ?>
<html>
<!-- пролог -->
<? foreach $i ($ii) { //простой код, визуализирующий заполненные структуры ?>
<tr>
<td><? echo $i.a ?></td>
<td><? echo $i.b ?></td>
</tr>
<? } ?>
<!-- эпилог -->
</html>
В результате мы вплотную подошли к идее HTML-шаблонов, о которой я расскажу в следующей главе. продолжение следует
Андрей Мельников © 2001
ICQ #29804514
Внимание! Вся информация, размещенная на этом сайте в разделах "статьи" или "рассылки", является собственностью NunDesign. О полном или частичном использовании материалов вы можете узнать на странице "авторское право".
