Мы начинаем цикл уроков, посвященных созданию собственных CGI - сценариев. Наши занятия не являются абсолютно полным и всеобъемлющим курсом языка Perl. В первую очередь мы рассмотрим только те аспекты, которые позволят создавать относительно несложные, но полезные и эффективные сценарии.
Вот примерный круг вопросов. Не каждый из этих пунктов будет строго соответствовать одному уроку. Для некоторых может понадобиться и больше. Однако, новый материал будет появляться строго раз в неделю, по средам.
А пока, небольшое вводное занятие на тему
Каждому человеку свойственно гордиться талантами, которыми он обладает. А еще больше - теми, которых у него нет. Причем, по моему опыту это особенно характерно для компьютерного мира. Каждый, кто умеет печатать на клавиатуре двумя пальцами, хочет считаться крутым программистом. Соответственно, человек прочитавший книгу "Освой самостоятельно программирование за 1 день" хочет считаться экспертом по всем операционным системам. Эта особенность компьютерщиков и привела к появлению языка Perl. Главным достоинством этого языка является его умение эффективно спрятать большинство особенностей операционной системы Unix, вызывающих у непосвященного шок. Учитывая, что большинство серверов Internet работают именно под Unix, а большинство авторов этих серверов - под Windows, язык способный преодалеть барьер, является большим подспорьем.
Однако, в каждой бочке меда- по ложечке дегтя. Поскольку Perl - интерпретируемый язык, программы созданные на нем значительно менее эффективны, чем программы на языке С. Потеря эффективности окажется практически незаметной для простых программ, но будет весьма существенной для сложных. Таким образом, Perl максимально подходит для решения простых задач, таких как создание счетчиков, гостевых книг и поиска в простых базах данных.
Еще одна ложечка дегтя связана с тем, что Perl ведет свое происхождение из мира Unix. А следовательно - он сохраняет некоторые особенности этой системы. Они не служат значительным препятствием, но учитывать их придется. Учитывая, что для DOS/Windows существует большое количество компиляторов С/C++ уровня "для чайников", для серверов работающих под управлением Windows, более подходящим выбором будет все-тка С.
Ненсмотря на эти ложки дегтя, в качестве языка для разработки сценариев, Perl предпочтительнее чем Ява. Так, он не устапает Яве по скорости исполнения, однако значительно превосходит ее по простоте.
Таким образом, язык Perl является удобным средством, позволяющим быстро разрабатывать программы, решающие 90% задач, обычно возлагаемых на CGI - сценарии. Особенно в случае когда необходимо управлять сервером, работающим под Unix, а изучать тонкости этой системы - не хочется. Именно на такую аудиторию и будут рассчитаны наши уроки.
Практически ни один сценарий не может обойтись без операций ввода - вывода. В настоящем занятии будут рассмотрены основные принципы осуществления этой операции на языке Perl
.При работе с Perl, надо учитывать, что он ведет свое происхождение из Unix, и несет отчетливый отпечаток ее идеологии. Одним из примеров подход к операциям файлового ввода-вывода как к операциям с потоками.
Занятие состоит из следующих частей:
Начнем с начала - создание и открытие файлов.
И создание и открытие файлов осуществляется одной и той же функцией
open. В простейшем случае ее вызов выглядит так:open("Имя потока", "имя файла");
Имя потока - это имя потока, который должен быть связан с файлом. В программе для обращения к файлу мы должны использовать именно его.
Имя файла - название файла с которым мы хотим поработать.
Использование двойных кавычек с точки зрения Perl, означает, что заключенное в них выражение представляет собой строку.
Первое что обращает на себя внимание - отсутствие указания в явном виде на то, для какой именно цели файл открывается. Так, если файл уже существует, должен ли он быть очищен, или нет. Можно в этот файл записывать информацию, или он предназначен только для чтения ?
Естественно, при использовании функции open, все это на самом деле указывается, но в виде символов, добавляемых к имени файла спереди.
Всего используется три символа. Причем некоторые могут комбинироваться между собой.
Вот эти символы:
Знак |
Функция |
Совместим с |
Несовместим с |
< |
Открытие для чтения. Если файла нет - возникает ошибка |
< |
> и < |
> |
Создание файла для записи. Чтение также возможно |
> и + |
< |
+ |
Открытие для чтения - записи |
> и < |
нет |
Возможны следующие комбинации:
Комбинация |
Функция |
<+ |
Открыть для чтения - записи. При отсутствии файла возникает ошибка |
+> |
Создать файл для чтения - записи. Если файл существует - его содержимое теряется |
>> |
Открыть или создать для дополнения |
+>> |
Открыть или создать для чтения - записи |
Когда файл открыт, воод из него выполняется крайне просто - присвоемнием переременной значения. Обращаем внимание, что язык Perl определяет типы данных самостоятельно. На практике, такой способ чтения данных эквивалентен простому чтению строки. Несколько строк за один вызов прочитать нельзя. Поэтому, приходится выполнять чтение в цикле. Впрочем, в
простейшем счетчике нам достаточно прочитать только одну строку.Ну вот, настола время посмотреть на текст программы простейшего счетчика посещений. Первая строка программы - обязательный комментарий, указывающий путь к интерпретатору Perl. В зависимости от его реального расположения на диске, может меняться.
#!/usr/bin/perl #Простейший счетчик. При каждом вызове увеличивает значение, #хранящееся в файле с именем count.cnt на единицу и возвращает #н возвращает новое значение.Авторы - Леонид Садофьев, Лариса Работнова $counterfile="count.cnt"; #имя файла содержащего значение счетчика unless (open(COUNTER,"+<$counterfile")) #если не удалось открыть файл { $counter=0; #обнуляем значение счетчика } else #если файл открыт успешно, { $counter=<COUNTER>; #читаем значение счетчика } close(COUNTER); #закрываем файл $counter=$counter+1; #увеличиваем счетчик на единицу open(COUNTER,"+>$counterfile"); #открываем файл со сбросом содержимого print COUNTER $counter; #записываем новое значение счетчика close (COUNTER); #закрываем файл print "Content-type: text/html\n\n"; #вот так должен начинаться ответ #CGI - сценария. #Пустая строка - обязательна print <<EOF #Теперь можно генерировать HTML страницу <html> <head> <title>Counter value</title> </head> <BODY> <center> <br> $counter <br> </body> </html>
Счетчик может быть вызван через директиву включения типа
или с помощью тэга HTML image src. Естественно, на вашем сервере счетчик может быть размещен в другом каталоге, а не только в cgi-bin
То что мы привели является настолько упрощенным вариантом, что его даже нельзя назвать счетчиком посещений. Это только счетчик показов страницы. Так, он будет срабатывать при любой перезагрузке страницы, даже если она выполняется одним и тем же пользователем, причем непрерывно. Кроме того, поскольку этот счетчик работает с фиксированным именем файла, его нельзя установить на несколоко страниц сразу.
Чтобы усовершенствовать счетчик, устранив эти два основных дефекта, надо уметь получать и использовать в сценарии информацию от сервера. Этому и будет посвящено следующее занятие.
Предыдущие занятия:
ПервоеПервый, и самый очевидный недостаток счетчика, разобранного ранее - работа с фиксированным именем файла, что не позволяет использовать без изменений это текст для нескольких страниц. В тоже время, даже начинающий Веб - мастер знает, как важно отслеживать потоки посетителей и определять наиболее и наименее популярные страницы. Для решения этой задачи модифицируем счетчик, так чтобы он определял для какой конкретно страницы он вызван. Самое простое и очевидное решение - передавать название страницы в качестве параметра при вызове программы счетчика. В настоящем занятии мы посмотри как это делается.
Занятие состоит из следующих частей:
В настоящее время существуют два способа вызова сценария с передачей ему параметров. Это методы Get и Post. Мы не будем подробно обсуждать достоинства и недостатки каждого из этих методов, а ограничимся только минимально необходимой информацией. Метод GET - это метод передачи принимаемый по умолчанию. Иными словами, если метод не указан явно, то сервер
предполагает, что данные передаются по методу Get. В соответствии со спецификацией Standart CGI, при вызове сценария сервер заносит такие данные в переменную среды QUERY_STRING. Второй метод - POST - предназначен для передачи больших объемов данных и данные помещаются в стандартный входной поток сценария. Впрочем, при работе со счетчиком нам понадобится только метод GET,Полная автоматизация передачи параметров достигается только при работе с формами. Однако, передать параметры вполне можно и вручную. Как это сделано в следующем примере:
В данном случае вызывается сценарий с именем counter.cgi, расположенный в каталоге cgi-bin. В качестве параметра сценарию передается строка mainpage. Сам вызов осуществляется как правило через директивы включенияна стороне сервера - команду серверу, оформленную как комментарий HTML. Создавать форму для этого не требуется.
Хэши являются одной из самых удачных находок языка Perl и применяются в программах чрезвычайно широко. Более того, они почти не имеют аналогов в других языках программирования. Что же это такое ?
Хеш представляет собой набор пар ключ-значение. При этом, как ключ, так и значение, могут иметь любой тип - числовой, строковый и т.д. Ключ используется для доступа к значению. Вот несколько простых примеров работы с хэшем:
Действие |
Синтаксис |
Объявление переменной типа хэш |
%MyHash; |
Присвоение значения ключу. Если заданный ключ отсутствует - создается новая пара |
$MyHash{'NewKey'}=$NewValue; |
Изменение значения |
$MyHash{'NewKey'}+=3; |
Чтение значения |
$Result=$MyHash{'NewKey'}; |
При обращении к значению, соответствующему неизвестному ключу возвращается значение undef.
Для доступа к переменным окружения в Perl поддерживается встроенный хэш с именем %ENV. Таким образом, доступ к переданным по методу GET данным осуществляется следующим образом:
$Data=$ENV{'QUERY_STRING'}; #Одинарные кавычки - строковая константа.
В нашем примере переменная $Data примет значение mainpage. Остается только использовать это значение для вычисления имени файла, содержащего значение счетчика для требуемой страницы.
Надо обратить внимание, что в этом месте возникает потенциальное нарушение безопасности. Так, если передаваемый параметр используется как имя файла напрямую, то недобросовестный посетитель может подставить вместо него какое-либо другое имя и просмотреть содержимое файла или каталога, которое не предназначено для показа. От этой беды существуют два спасения. Первый -
преобразование имени страницы в имя файла по некоему алгоритму (задание строго определенного пути, расширения файла и т.д.) или работа через файл, содержащий пары имя страницы - имя файла счетчика. Первый путь проще, зато второй безопаснее. Мы для простоты воспользуемся первым способом.#!/usr/bin/perl #Счетчик посещений. При каждом вызове увеличивает значение, #хранящееся в файле с именем,вычисленным на основе передаваемого параметра на единицу и возвращает #н возвращает новое значение.Авторы - Леонид Садофьев, Лариса Работнова $counterfile; #переменная для хранения имени файла содержащего значение счетчика $Data=$ENV{'QUERY_STRING'}; #теперь $Data содержит переданные сценарию данные $counterfile="../counters/$Data.cnt"; #используем фиксированные имя каталога #и расширение файла - безопасность превыше всего ! unless (open(COUNTER,"+<$counterfile")) #если не удалось открыть файл { $counter=0; #обнуляем значение счетчика } else #если файл открыт успешно, { $counter=<COUNTER>; #читаем значение счетчика } close(COUNTER); #закрываем файл $counter=$counter+1; #увеличиваем счетчик на единицу open(COUNTER,"+>$counterfile"); #открываем файл со сбросом содержимого print COUNTER $counter; #записываем новое значение счетчика close (COUNTER); #закрываем файл print "Content-type: text/html\n\n"; #вот так должен начинаться ответ #CGI - сценария. #Пустая строка - обязательна print <<EOF #Теперь можно генерировать HTML страницу <html> <head> <title>Counter value</title> </head> <BODY> <center> <br> $counter <br> </body> </html>
Итак, мы несколько усовершенствовали счетчик, научив его определять имя страницы. Однако, он еще будет срабатывать чаще чем надо - например при случайной перезагрузке страницы. Ликвидации этого дефекта с помощью анализа переменных окружения - тема следующего занятия.
Предыдущие занятия: