Для журнала "Мой компьютер". В журнале публиковалось под названием "Perl'ы для веб-мастера".

Perl'ы для веб-мастера

Евгений Гривастов tw@tv-agent.net

(Продолжение. Начало в МК № 45, 47, 48, 49, 50 (2000))

В предыдущих статьях этого цикла вы уже опробовали основные приемы программирования и познакомились с синтаксисом и способами использования основных операторов языка Perl. Так, вы знаете, что если параметры вызова скрипта передаются размещением их после знака вопроса в URL вызова скрипта, то получить строку параметров можно из переменной окружения $ENV{'QUERY_STRING'}. У вас в арсенале есть небольшая стандартная подпрограмма, преобразующая данные, полученные от html формы в обычный хэш. Научились основным приемам в работе с текстовыми файлами ("МК" №№ 45, 47), получению других основных переменных окружения ("МК" № 47), рассмотрели основные операторы циклов и операции сравнения ("МК" №50), немного познакомились с регулярными выражениями ("МК" № 48). В этот раз давайте сделаем скрипты модерации записей в нашей гостевой книге ("МК" №50).

Глава 12. Модерация гостевой книги.

Для этого нам понадобится два скрипта: один будет показывать какие записи присутствуют в нашей гостевой книге, а второй - вносить в них изменения. Первый сделаем на основе скрипта просмотра записей гостевой книги (изготовленного нами в прошлый раз). Скопируйте файл showgb.cgi в файл showgbm.cgi. Теперь немного изменим наш showgbm.cgi следующим образом (изменения будут прокомментированы по ходу листинга):

#!/usr/local/bin/perl

$gbid=$ENV{'QUERY_STRING'};
($gbid,$numzap)=split(/&/,$gbid);

$dir='/home2/your_domen/public_html/gb/';

$filename=$dir.'listgb.txt';
open (FLFL, "$filename");
foreach $stroka (<FLFL>) {
($id,$gbdir)=split(/::/,$stroka);
last if ($id eq $gbid);
}
close FLFL;

exit if ($id ne $gbid);

$filename=$dir.$gbdir.'/countf.txt';
open (FILE, "$filename");
$countf = <FILE>;
close(FILE);

exit if ($countf<$numzap);

$numzap=$countf if (! $numzap);

print "Content-Type: text/html\n\n";
print '<html><head></head><body><p><b>Удаляем запись</b></p><hr>';

for ($iii=$countf; $iii>=1; $iii--) {
if ($iii==$numzap) {
print '<b>'.$iii.'</b> ';
} else {
# В следующей строке изменим имя скрипта просмотра на имя скрипта, который мы сейчас делаем (showgb.cgi на showgbm.cgi).
print '<a href=http://www.your_domen.com/cgi-bin/showgbm.cgi?'.$gbid.'&'.$iii.'>'.$iii.'</a> ';
} #if
} #for

# Теперь это будет не просто страница просмотра, а веб-форма в которой можно будет отметить записи, подлежащие удалению
print '<form action="http://your_domen.com/cgi-bin/delgb.cgi" method="post">';

# Чтобы пронумеровать строки именно в том порядке, в котором они расположены в файле - будем считывать их напрямую из файла
$filename=$dir.$gbdir.'/'.$numzap.'.txt';
open (FILE, "$filename");

# Переменная $i будет счетчиком строк в файле.
$i=0;
foreach $stroka (<FILE>) {
($nik,$email,$message)=split(/|/,$stroka);
print '<hr>';
# Перед каждой записью поместим checkbox с номером этой записи в файле в качестве значения
print '<input type="checkbox" name="numdel" value='.$i.'>';
print ' '.$email.', '.$nik.'<br>'.$message.'<hr>';
$i=$i+1;
} #foreach
close(FILE);

print '<input type="hidden" name="gbid" value='.$gbid.'>';

# Нам понадобится еще и номер файла, из которого удалять отмеченные записи
print '<input type="hidden" name="numzap" value='.$numzap.'>';
print '<input type="submit" value="Удалить"></form>';

print '</body></html>';

exit;

Второй скрипт будет называться delgb.cgi. Функцией его будет удалить из файла-архива отмеченные нами записи.

#!/usr/local/bin/perl
&GetFormInput;
$gbid=$field{"gbid"};
$numdel=$field{"numdel"};
$numzap=$field{"numzap"};

# Если записей к удалению несколько, то их номера будут в переменной $numdel записаны через запятую. Разделим их и поместим этот список в массив @numdel
@numdel=split(/\,/,$numdel);

$dir='/home2/your_domen/public_html/gb/';
$filename=$dir.'listgb.txt';
open (FLFL, "$filename");
foreach $stroka (<FLFL>) {
($id,$gbdir)=split(/::/,$stroka);
last if ($id eq $gbid);
}
close FLFL;
exit if ($id ne $gbid);

$filename=$dir.$gbdir.'/'.$numzap.'.txt';
open (FILE, "+<$filename");
flock (FILE,2);
$i=0;
# Считываем по порядку все строки из файла
foreach $stroka (<FILE>) {
# Если номер строки не содержится в списке строк, предназначенных к удалению (узнаем это с помощью подпрограммы DelStr, передавая ей в качестве параметра номер текущей строки) - то заносим эту строку в массив @stroki.
@stroki=(@stroki, $stroka) if (! DelStr($i));
}
seek (FILE,0,0);
truncate(FILE,0);

# Запишем строки из массива обратно в файл. Напомню, что в массив мы помещали только строки не предназначенные к удалению.
while ($stroka=(@stroki)) {
print FILE "$stroka\n";
}
close(FILE);

# Покажем снова страницу администрирования с изменениями
print "Location: http://www.your_domen.com/cgi-bin/showgbm.cgi?".$gbid."&".$numzap."\n\n";

exit;

# Подпрограмма, которая будет определять, есть ли в списке строк, предназначенных к удалению, строка с номером, переданным этой подпрограмме в качестве параметра
sub DelStr {
my ($ret) = 0;
while ($numdel=(@numdel)) {
$ret=1 if ($numdel==$_[0]);
}
return $ret;
}

sub GetFormInput {
# Точно такая же подпрограмма, как и во всех предыдущих скриптах.
}

Итак, с администрированием гостевых книг покончили. :-)

(…продолжение следует…)