Perl'ы для веб-мастера
🕛 13.10.2006, 15:02
Вы можете быть профессиональным вебмастером, можете просто создавать и поддерживать свою домашнюю страницу, но в определенный момент вы обязательно должны почувствовать (если уже не почувствовали), что возможностей одного лишь языка HTML не хватает - сайту нужна интерактивность, взаимодействие с посетителем. Здесь вам на помощь прийдет Perl - простой и в то же время полнофункциональный язык программирования. С помощью Perl можно создавать как простые CGI-скрипты, так и сложные программы, взаимодействующие с базами данных. С чего же начать? Об этом мы сегодня поговорим.Чтобы решить основные задачи, стоящие перед вебмастером, без необходимости многомесячного изучения языков программирования, мы опустим длительное обучение теории и сразу перейдем к практике. Учиться будем в процессе создания скриптов, которые вы сможете опробовать на своем сайте.
Что необходимо знать о сервере
Прежде чем писать CGI-скрипты, необходимо узнать некоторую информацию о сервере, на котором эти скрипты будут работать. Всю эту информацию можно получить у провайдера, где находится сайт. Бесплатные службы, предоставляющие место под страницы, обычно размещают такую информацию в своих "хелпах", в разделах, посвященных CGI и т. п. Адреса серверов, которые разрешают выполнение CGI-скриптов, мы публиковали в прошлом номере МК.
Наиболее важный параметр из тех, что необходимо знать - путь к интерпретатору Perl на сервере, который следует указывать в первой строке каждой программы, написанной на Perl. Обычно она имеет вид:
#!/usr/bin/perlТакую строку мы будем использовать в дальнейших примерах.
Еще обязательно знать полный путь к cgi-bin-директории вашего сайта и полный путь к его основной (корневой) директории. Это не адрес, начинающийся с http:// - это полный путь от корневой директории сервера, на котором находится ваш сайт, и имеющий вид:
/home2/your_domen/public_html/
Чтобы скрипт имел возможность отправлять письма, понадобится узнать путь к почтовой программе (sendmail). Он может выглядеть примерно так:
/usr/sbin/sendmail
Инструменты
Для написания скриптов на Perl'е, не обязательно устанавливать какой-либо специальный софт - подойдет и любой текстовый редактор, тот же "Блокнот", входящий в состав Windows. Но все-таки упомяну пару инструментов, которые помогут упростить написание и отладку скриптов. Прежде всего, понадобится интерпретатор Perl для Windows, который можно загрузить со страницы http://www.activestate.com/ActivePerl/download.htm (либо выбрать другие варианты адресов с сервера http://www.perl.com/). А для программирования и отладки самый удобный, на мой взгляд, инструмент - это Perl Builder (http://www.solutionsoft.com/). Кроме пошаговой отладки с возможностью просмотра по ходу значений переменных, имеется функция автоматической генерации некоторых скриптов. А вообще, существует достаточно много различного программного обеспечения, которое помогает в создании и отладке программ на Perl - мы обязательно с ним ознакомимся в дальнейшем.
То, что я описал эти инструменты именно сейчас и буду время от времени упоминать о них в статье, не означает, что они обязательны. Вы спокойно можете набирать все примеры в Блокноте, просто тогда вы не сможете производить отладку скриптов в процессе их написания - это прийдется делать прямо на сервере.
Создаем счетчик посещений
Есть множество рейтингов, предоставляющих счетчики посешений, собирающих статистику. Взамен они требуют установить у вас на сайте свою кнопку. Но что делать, если вы не гонитесь за высоким положением в рейтинге и не желаете вставлять в свою страницу кнопку рейтинга? Вам просто нужно считать посетителей и собирать некоторую статистику. Или почему бы не проконтролировать правильность информации, собранной чужим счетчиком? А может, вы хотите создать собственный рейтинг? ОК, давайте сделаем сначала простейший счетчик, а затем превратим его в систему сбора статистики и удобного просмотра собранной информации. А заодно и научим генерировать картинку счетчика.
Начнем с простейшего текстового счетчика. Правда, чтобы он работал, необходима поддержка сервером инструкций SSI (Server Side Includes) - об этом также узнайте у хостинг-провайдера.
Создайте в текстовом редакторе два файла и сохраните их на своем диске с именами count.cgi и count.txt соответственно. Второй из них пусть будет пустым, а в первом наберите следующий текст:
#!/usr/bin/perl $namefile="count.txt"; open (COUNTFILE, "$namefile"); $count = <COUNTFILE>; close(COUNTFILE); chomp ($count); $count=$count + 1; open (COUNTFILE, ">$namefile"); print COUNTFILE "$count"; close(COUNTFILE); print "Content-Type: text/html\n\n"; print "$count"; exit;Если вы набирали текст в Perl Builder, то, выбрав в меню Run/Debug > Check Syntax With -w Flag, сможете сразу проверить скрипт на наличие ошибок. Если ошибки присутствуют - то Perl Builder выдаст соответствующие сообщения с номером строки, в которой содержится ошибка.
Теперь с помощью FTP-клиента скопируйте оба файла в cgi-bin-директорию своего сервера. Отметим, что делать это надо в режиме ASCII. После этого установите права доступа (команда CHMOD) для count.cgi - 755, а для count.txt - 666. Осталось вставить вызов скрипта в HTML-страницу. В том месте страницы, где вы хотите увидеть счетчик посещений вставьте строку:
<!-#exec cgi="/cgi-bin/count.cgi"->где /cgi-bin/count.cgi - полный путь к файлу скрипта от корневой директории вашего сайта. Т. е. если полный путь к скрипту выглядит как http://your-domen.com/cgi-bin/count.cgi, то в вызове скрипта пишем /cgi-bin/count.cgi.
Теперь можно загрузить страницу на сервер и открыть ее в браузере. Вы увидите цифры - показания счетчика, увеличивающиеся при каждом вызове страницы. Осталось разобраться, что же мы такое сделали.
Чтобы вы хоть немного могли понимать, о чем идет речь, предлагаю некоторые начальные сведения о том, "что есть что в Perl".
Имена скалярных переменных всегда начинаются со знака "$". Например: $ind. Скалярная переменная - это переменная, содержащая только одно значение. В отличие от массива (списка), в котором содержится множество значений. Имя массива всегда начинается со знака "@". Например: @ind.
Итак, о том, что первая строка скрипта указывает, где искать интерпретатор Perl, вы уже знаете.
Строка:
$namefile="count.txt";
помещает в переменную $namefile имя файла count.txt;
open (COUNTFILE, "$namefile");
открывает файл count.txt для чтения, связывая название файла с дескриптором COUNTFILE;
$count = <COUNTFILE>;
считывает из файла последнее значение счетчика. Так как в первый раз считывать нечего, то в переменной $count появится значение "0";
close(COUNTFILE);
закрывает файл;
chomp ($count);
если в конце считанной строки присутствует символ перевода строки (в Perl имеет вид "\n") - он будет удален. В нашем случае такого символа нет. Но лучше перестраховаться, чем потом искать непонятные ошибки.
$count=$count + 1;
увеличиваем значение счетчика на единицу. Эту операцию можно также записать вот так:
$count++;
но для наглядности будем использовать предыдущий вариант.
open (COUNTFILE, ">$namefile"); откроем файл count.cgi для записи, уничтожив (символ ">") его содержимое print COUNTFILE "$count"; запишем в файл новое значение счетчика close(COUNTFILE); закроем файл print "Content-Type: text/html\n\n"; print "$count"; передаем новое значение счетчика в качестве результата работы скрипта, чтобы сервер включил это значение в состав HTML-страницы - в том месте, где находится строка <!-#exec cgi="/cgi-bin/count.cgi"-> exit;конец выполнения программы (без этого можно обойтись, но почему бы не следовать традициям).
Небольшие усовершенствования нашего счетчика
Итак, мы научились считать заходы на нашу страницу. Допустим, мы не хотим, чтобы файл count.txt со значениями счетчика лежал в директории cgi-bin. Давайте создадим на сайте отдельную директорию, назовем ее, например, mystat, куда и скопируем файл count.txt. Не забудьте назначить файлу права доступа 666.
Теперь надо в нашем скрипте указать новый путь к файлу count.txt. Помните строку:
$namefile="count.txt";
казалось бы, ненужную? Ведь в принципе имя файла можно было бы указать и непосредственно при его открытии. Зато теперь, когда нам понадобилось изменить путь к файлу, достаточно изменить только эту строку.
Добавим к названию файла полный путь к директории с файлами сервера и название директории, в которой этот файл у нас лежит. Например, если полный путь выглядит так:
/home2/your_domen/public_html/
добавим имя созданной нами директории и получим следующее:
$namefile="/home2/your_domen/public_html/mystat/count.txt";
Модернизируем. Что будет, если в браузере зайти на страницу со счетчиком и нажать "обновить"? Правильно - значение счетчика увеличится на единицу. Причем каждая новая загрузка страницы в браузер будет вызывать увеличение значения счетчика. Давайте научим наш счетчик отслеживать заходы подряд с одного IP-адреса и не засчитывать такие заходы. Для этого создадим файл с названием, например, ip.txt и положим его в ту же директорию mystat на сервере. Назначим ему права доступа 666. В этом файле мы будем хранить IP-адрес последнего посетителя, засчитанного счетчиком. Теперь осталось добавить соответствующую проверку в скрипт.
Прежде всего добавим переменную, содержащую путь к файлу:
$nameipfile="/home2/your_domen/public_html/mystat/ip.txt";
Теперь нам надо получить собственно IP-адрес посетителя. Содержится он в переменной $ENV{"REMOTE_ADDR"}, значение которой передается скрипту браузером посетителя вместе с запросом. Присвоим это значение переменной $ip:
$ip=$ENV{"REMOTE_ADDR"};
Теперь считаем из файла ip.txt значение последнего IP-адреса, сравним его с полученным. Если они совпадают, тогда не засчитаем заход (завершив работу скрипта), если же не совпадают - увеличим значение счетчика и запишем новое значение IP-адреса в файл ip.txt:
open (IPFILE, "$nameipfile"); $ipold = <IPFILE>; close(IPFILE); chomp ($ipold); if ($ipold eq $ip) { exit; } open (IPFILE, "$nameipfile"); print IPFILE "$ip"; close(IPFILE);Теперь точность показаний счетчика стала немного выше. Но как он поведет себя, если на нашу страницу зайдет одновременно два посетителя? Одновременно два процесса попытаются произвести запись в файл с показаниями счетчика, в результате чего все данные файла могут быть потеряны. Чтобы этого не допустить, необходимо запретить одновременный доступ к файлу нескольких процессов. Сделать это можно с помощью функции flock, которая позволяет заблокировать файл, связанный с дескриптором, от доступа из других скриптов. Немного изменим процесс работы с файлом count.txt:
open (COUNTFILE, "+<$namefile");
flock (COUNTFILE,2);
$count =readline(*COUNTFILE);
chomp ($count);
$count=$count + 1;
seek (COUNTFILE,0,0);
truncate(COUNTFILE,0);
print COUNTFILE "$count";
close(COUNTFILE);
Теперь поясненим наши действия.
1) Открываем файл для чтения и записи:
open (COUNTFILE, "+<$namefile");
2) Блокируем файл от доступа из других одновременно запущенных процессов выполнения скрипта
flock (COUNTFILE,2);
3) Считываем значение счетчика из файла
$count =readline(*COUNTFILE);
4) Удаляем символ конца строки (если он случайно неизвестно откуда появился)
chomp ($count);
5) Увеличиваем значение счетчика
$count=$count + 1;
6) Перемещаем указатель позиции в файле на его начало
seek (COUNTFILE,0,0);
7) Усекаем длину файла до текущей позиции (т. е. до начала файла, куда мы передвинули этот указатель предыдущей строкой)
truncate(COUNTFILE,0);
8) Записываем в файл новое значение счетчика
print COUNTFILE "$count";
9) Закрываем файл, одновременно снимая с него блокировку
close(COUNTFILE);
Итак, весь скрипт теперь будет иметь следующий вид:
#!/usr/bin/perl $namefile="/home2/your_domen/public_html/mystat/count.txt"; $nameipfile="/home2/your_domen/public_html/mystat/ip.txt"; $ip=$ENV{"REMOTE_ADDR"}; open (IPFILE, "$nameipfile"); $ipold = <IPFILE>; close(IPFILE); chomp ($ipold); if ($ipold eq $ip) { exit; } open (IPFILE, "$nameipfile"); print IPFILE "$ip"; close(IPFILE); open (COUNTFILE, "+<$namefile"); flock (COUNTFILE,2); $count =readline(*COUNTFILE); chomp ($count); $count=$count + 1; seek (COUNTFILE,0,0); truncate(COUNTFILE,0); print COUNTFILE "$count"; close(COUNTFILE); print "Content-Type: text/html\n\n"; print "$count"; exit;(...продолжение следует...)