А теперь создадим форму, запрашивающую основную информацию о пользователе и позволяющую пользователю комментировать статьи. После ввода информации в форму, сценарий Perl обрабатывает и сохраняет ее в базе данных с помощью оператора INSERT.
Для удобства исходная форма и страница с результатом были включены в один и тот же сценарий Perl - post.cgi. При этом для принятия решения, какой страницей следует пользоваться, используется переменная $submit. Ниже представлена исходная форма.
Добавление комментариев
Листинг 20.35.
#!/usr/bin/perl
# считать необходимые модули use DBI;
use CGI;
# инициировать объект CGI $cgi = new CGI();
# распечатать HTTP- заголовки print $cgi->header();
# распечатать заголовок страницы print $cgi->start_html;
# проверить ввод в исходную форму if (!$cgi->param('submit'))
{
# получить URL текущего сценария $url = $cgi->url();
# проверка идентификатора статьи if (!$cgi->param('aid'))
{
print " Невозможно найти идентификатор статьи, завершение ра­боты
die;
}
else 
{
$aid = $cgi->param('aid');
# проверить: это ответ или новая ветвь if ($cgi->param('creply'))
{
$creply = $cgi->param('creply');
}
# отобразить форму print <<FORM;
<form method="POST" action="$url">
<input type="hidden" name="creply" value="$creply"> <input type="hidden" name="aid" value="$aid"> <table border="0" cellspacing="5" cellpadding="0"> <tr>
<td colspan=2>
<font face="Verdana, Arial" size="2" color="Black"><b>Ваш комментарий:</b></font><p>
</td>
</tr> <tr>
<td><font face="Verdana, Arial" size="2" color="Black">Электронный address</font></td><td><input type="text" name="email" size="25"></td>
</tr>
<tr>
<td><font face="Verdana, Arial" size="2" color="Black">Тема</font></td>
<td><input type="text" name="subject" size="2 5"></td>
</tr>
<tr>
<td><font face="Verdana, Arial" size="2" color="Black">Комментарий</font></td>
<td><textarea name="post" rows="5"></textarea></td>
</tr>
<tr>
<td colspan=2 align=center><input type="submit" name="submit" value="Добавить
комментарий"></td>
</tr>
</table>
</form>
FORM
}
else
{
# форма введена, обработать данные
}
# распечатать нижний колонтитул страницы print $cgi->end_html;
Это достаточно стандартная форма, содержащая поля, связанные с полями в таблице comments. Как и в предыдущих сценариях, идентификатор статьи передается сценарию перед любой обработкой. Однако в отличие от предыдущих сценариев, этот также проверяет, является ли комментарий ответом на другие комментарии, т.е. принадлежит уже существующей ветви или начинает новую ветвь. Для этого выполняется проверка наличия переменной $creply. 
Заметим, что из этой формы идентификатор статьи и переменная $creply (если она имеется) передается дальше сценарию обработки данных формы в виде скрытой переменной. Обратим внимание на использование объектного метода url(), который возвращает полный URL текущему сценарию. Так как для обработки данных, введенных в форме, вызывается один и тот же сценарий, этот метод предлагает удобный и переносимый способ задания значения для атрибута ACTION этой формы.
Добавление комментариев
После ввода данных в форму, аналогичный сценарий вызывается для обработки данных. В этом случае из-за наличия переменной $submit условная проверка, проведенная в начале сценария, направит работу алгоритма сценария по второй ветви условного оператора. В ней тестируются данные, введенные в форме, а для сохранения их в базе данных используется оператор INSERT.
Листинг 20.36.
#!/usr/bin/perl
# считать необходимые модули use DBI;
use CGI;
# инициировать объект CGI $cgi = new CGI();
# распечатать HTTP- заголовки print $cgi->header();
# распечатать заголовок страницы 
print $cgi->start_html;
# проверить ввод в исходную форму
if (!$cgi->param('submit'))
{
# распечатать форму
}
else
{
# проверка идентификатора статьи if (!$cgi->param('aid'))
{
print " Невозможно найти идентификатор статьи, завершение рабо­ты
die;
}
else
{
$aid = $cgi->param('aid');
}
# проверить: это ответ или новая ветвь if ($cgi->param('creply'))
{
$creply = 0;
}
else
{
$creply = $cgi->param('creply');
}
# проверить адрес электронной почты if (!$cgi->param('email'))
{
$email = 'anonymous';
}
else
{
$email = $cgi->param('email');
}
# проверка темы
if (!$cgi->param('subject'))
{
$subject = "No subject';
}
else
{
$subject = $cgi->param('subject'); $post = $cgi->param('post');
}
# подключиться к базе данных
my $dbh = DBI->connect("DBI:mysql:database=dbl;host=localhost", "root", "pass',
('RaiseError' => 1));
# добавить комментарий в таблицу
my $sth = $dbh->do('INSERT INTO comments (aid, csubject, cpost, cemail, creply,
ctimestamp) VALUES ('$aid', '$subject', '$post', .$email', '$creply',
NOW ())");
# закрыть соединение с базой данных $dbh->disconnect(); 
# распечатать подтверждающее сообщение print <<MSG;
<font face="Verdana, Arial" size="2" color="Black"> ваш комментарий сохранен. <a href="article.cgi?aid=$aid">Щелкните</a> для чтения других комментариев</a>. </font>
MSG
}
# распечатать нижний колонтитул страницы print $cgi->end_html;
Этот сценарий просто проверяет переменные формы, исправляет пустые, а затем добавляет данные в базу данных. Если это новый комментарий, а не ответ на уже существующий, переменной $creply присваивается значение 0. Успешное добавление данных приводит к выводу страницы с подтверждением.