ГлавнаяПроектыФотографияМатериалыКарта узлаО себе(версия для печати)

Программирование сценариев для web-серверов

читайте также по теме: Управляемый сайт

Приведённый здесь текст был написан мной на заре моего знакомства с программированием для web, когда я постигал азы CGI-интерфейса. Можеть быть, для вас будет более интересен другой материал — «Управляемый сайт».

Для того чтобы создать свою страничку в глобальной сети сейчас достаточно приложить совсем немного собственных усилий, но чтобы «родной уголок» не выглядел набором «мертвых» статических HTML-документов, приходится использовать различные «динамические» технологии. Часть из них позволяет «оживить» HTML-документ в окне браузера пользователя (Gif89a, DHTML, JavaScript, VBScript, Flash, Java). Другая группа позволяет разработать «думающий» сайт, используя возможности сервера (CGI-приложения, SSI, PHP, ASP, Perl). Рассмотрим на небольшом примере возможности динамической генерации HTML-документов на стороне сервера с помощью сценариев PHP и ASP.

Существует много способов для создания динамических HTML-страниц, но страницы, формируемые с помощью серверных сценариев, имеют несколько неоспоримых преимуществ. По сравнению, например, со сценариями JavaScript или VBScript, которые не могут сохранять свое состояние (кроме как в «ключиках» клиентского браузера), серверные сценарии могут использовать ресурсы самого сервера для сохранения своего состояния или других данных. Кроме того, так как сценарии выполняются на стороне сервера, их не надо передавать по сети, и скорость выполнения таких сценариев не зависит от возможностей клиентской машины.

Гостевая книга

Типичным примером взаимодействия личного сетевого HTTP-узла является функционирование так называемой гостевой книги. Попробуем на этом примере рассмотреть и сравнить два вида сценариев PHP и ASP, применяемых на популярных web-серверах Apache и IIS соответственно.

Первая задача, которую необходимо решить, как передать и сохранить на сервере текст сообщения, посылаемый посетителем сетевого узла. В таких случаях вполне подходит CGI (Common Gateway Interface) механизм передачи параметров от пользователя к серверу. По спецификации CGI чтобы передать параметры приложению на сервере, надо либо разместить их в строке адреса URL (метод get), либо в самом HTTP-заголовке в виде переменных окружения (метод post). То есть, если в HTML-документе имеется форма с текстовыми полями ввода, то после нажатия на кнопку отправки запроса имеем:

Метод getМетод post
HTML-документ

<form action="myscript" method="get">
  <input type="text" name="Var1" value="Alex">
  <input type="text" name="Var2" value="Hello">
  ...
</form>
<form action="myscript" method="post">
  <input type="text" name="Var1" value="Alex">
  <input type="text" name="Var2" value="Hello">
  ...
</form>

приложение на стороне сервера
Сформированная строка адреса запроса:
myscript?Var1=Alex&Var2=Hello
Командная строка вызова CGI-приложения:
myscript Var1=Alex Var2=Hello
Таким образом, приложение myscript получит при вызове два параметра в командной строке Var1=Alex и Var2=Hello, из которых и сможет получить необходимые значения полей ввода Var1 и Var2.
Сформированная строка адреса запроса:
myscript
Переменные окружения в HTTP-заголовке
Var1=Alex
Var2=Hello

Таким образом, для доступа к значениям полей ввода приложению myscript необходимо выбрать значения у переменных окружения Var1 и Var2.

Отсюда сразу видно, что для передачи длинных строк более удобен метод post, так как ограничения на длину строки адреса запроса не актуальны. Зато метод get прост для передачи параметров при простом переходе по ссылке в HTML-документе и не требует наличия в документе формы с кнопкой отправки запроса.

Итак, в гостевой книге сообщение может иметь достаточно большую длину, поэтому будем использовать метод post. Допустим, у нас имеется следующая форма:

Ваше имя:

Электронный адрес:

Сообщение:

Допустим, PHP сценарий добавления новой записи называется addsign.php, а ASP — addsign.asp. Чтобы сообщения сохранялись на сервере, можно воспользоваться возможностью управления файлами на сервере. Так, для каждого сообщения можно создавать отдельный текстовый файл, содержащий его тело. Для удобства перечисления можно использовать числовое имя файла, а общее количество сообщений хранить в отдельном файле. Перечислим необходимые функции и методы соответственно:

PHPASP
Открытие текстового файла
integer fopen ( string Filename, string Ftatus )
Возвращает номер дескриптора открытого файла
Filename - имя открываемого файла
Status - вариант доступа к файлу, может принимать одно из следующих значений:
«r» - открыть для чтения
«w» - открыть для записи
«w+» - открыть для чтения и записи
Для начала надо создать объект файловой системы с помощью функции:
object CreateObject ( «Scripting.FileSystemObject» )
Возвращает объект файловой системы
Далее можно получить объект текстового файла с помощью метода объекта файловой системы:
object filesystem.OpenTextFile ( str Filename, int Status )
Возвращает объект, инкапсулирующий работу с текстовым файлом.
Filename - имя открываемого файла
Status - вариант доступа к файлу, может принимать одно из следующих значений:
1 - открыть для чтения
2 - открыть для записи
8 - открыть для чтения и записи
Чтение строки из текстового файла
string fgets ( integer FileDescriptor, integer StringLength );
Возвращает строку длины StringLength, считанную из открытого файла с дескриптором FileDescriptor.
str file.ReadLine
Возвращает строку, считанную из ассоциированного с объектом file открытого файла.
Запись строки в текстовый файл
fwrite ( integer FileDescriptor, string String, integer StringLength );
Записывает в открытый с дескриптором FileDescriptor файл StringLength символов строки String.
file.WriteLine str String
Записывает строку String в открытый файл, ассоциированный с объектом file.
Закрытие файла
fclose ( integer FileDescriptor );
Закрывает открытый с дескриптором FileDescriptor файл.
file.Close
Закрывает ассоциированный с объектом file открытый файл.
Доступ к переменным окружения
string getenv ( string EnvVariable );
Возвращает содержимое EnvVariable переменной окружения.
При запуске сценария переменные окружения автоматически отображаются в одноименные внутренние переменные PHP сценария.
str Request.ServerVariables ( str EnvVariable )
Возвращает содержимое EnvVariable переменной окружения.
Доступ к параметрам командной строки
При запуске сценария парметры командной строки автоматически отображаются в одноименные внутренние переменные PHP сценария. str Request.QueryString ( str ParamVariable )
Возвращает содержимое ParamVariable параметра командной строки.

Теперь код сценариев добавления новой записи. Будем считать, что через 1000 обращений новые сообщения начнут перезаписываться поверх старых, чтобы не переполнять дисковое пространство:

addsign.phpaddsign.asp
Получение значения переменных окружения

<?php
  $user	   = $_POST ["user"];
  $email   = $_POST ["email"];
  $message = $_POST ["message"];
<%
  set user    = Request.Form ("user")
  set email   = Request.Form ("email")
  set message = Request.Form ("message")

Получение текущего числа сообщений из файла «msgqty.txt»

$fname = "msgqty.txt";
  $fp = fopen ( $fname, "r" );
  $MsgQty = (integer) fgets ( $fp, filesize ($fname) );
  fclose ( $fp );
  set fs   = CreateObject ("Scripting.FileSystemObject")
  set file = fs.OpenTextFile ("msgqty.txt", 1)
  MsgQty = CInt ( file.ReadLine )
  file.Close

Формирование нового сообщения

  ++$MsgQty;
  if ( $MsgQty > 1000 ) $MsgQty = 1;
  $fname = "msg" . $MsgQty . ".txt";
  $fp = fopen ( $fname, "w" );
  $str = $user. "<a href=\"mailto:". $str . 
         $email. "\">". $email. "</a>";
  fwrite ( $fp, $str, strlen ($str) );
  $str = "Добавлено ". date ("h:i:s d.m.Y") . "<br>";
  fwrite ( $fp, $str, strlen ($str) );
  fwrite ( $fp, $message, strlen ($message) );
  fclose ( $fp );
  MsgQty = MsgQty + 1
  if MsgQty > 1000 then MsgQty = 1
  FName = "msg" + CStr ( MsgQty) + ".txt"
  fs.CreateTextFile ( FName )
  set file = fs.OpenTextFile (MsgFileName, 2)
  file.WriteLine ( user + "<a href=\"mailto:" + 
                   email + "\">" + email + "</a>")
  file.WriteLine ( "Добавлено " + Time + Date + "<br>" )
  file.WriteLine ( message )
  file.Close

Обновление количества сообщений

  $str = $MsgQty. "\n";
  $mfp = fopen ( "msgqty.txt", "w" );
  fwrite ( $mfp, $str, strlen ($str) );
  fclose ( $mfp );
?>
  set file = fs.OpenTextFile ("msgqty.txt", 2)
  file.WriteLine ( MsgQty )
  file.Close
%>;

А теперь код сценариев просмотра записей гостевой книги:

guestbook.phpguestbook.asp
Получение текущего числа сообщений из файла «msgqty.txt»

<?php
  $fname = "msgqty.txt";
  $fp = fopen ( $fname, "r" );
  $MsgQty = (integer) fgets ( $fp, filesize ($fname) );
  fclose ( $fp );
<%
  set fs = CreateObject ("Scripting.FileSystemObject")
  set file = fs.OpenTextFile ("msgqty.txt", 1)
  MsgQty = CInt ( file.ReadLine )
  file.Close

Вывод сообщений

for ( $i = $MsgQty; $i > 0; --$i )
{
  // Read messages</i>
  $fname = "msg" . ( string ) $i;
  $fname = $fname . ".txt";
  $fp = fopen ( $fname, "r" );
  $str = fgets ( $fp, filesize ($fname) );
  while ( !empty ( $str ) )
  {
    echo $str . "\n";
    $str = fgets ( $fp, filesize ($fname) );
  }
  fclose ( $fp );
  echo "<hr>";
}
?>
  for i = MsgQty to 1 step -1
    ' Read messages
    FName = "msg" + CStr(i) + ".txt"
    set file = fs.OpenTextFile (FName, 1)
    str = file.ReadLine
    while not file.AtEndOfStream
      str = file.ReadLine
      Response.Write str
    wend
    Response.Write "<hr>"
  next
%>

Очевидно, что при большом количестве сообщений пользователю придется долго ждать окончания загрузки страницы, поэтому имеет смысл гостевую книгу «разбить на страницы». Для этого хорошо подходит передача параметров методом get, так как можно с помощью обычной гиперссылки передавать номер сообщения, с которого надо начать показ. Например, до показа сообщений вывести строчку вида <a href=«guestbook.php?start=10»>Следующие сообщения...</a>, а в самом начале анализировать строку запроса на присутствие параметра start, и если он задан выдать соответствующую «порцию» сообщений.

Остальные модернизации «гостевой книги» ограничиваются только вашей фантазией. Удачи!

30 июля 2000—11 августа 2000
Максим Проскурня
© 1997–2016 Axofiber