РНР 5 в подлиннике

Страница 41 из 554


84

Часть I. Основы Web-программирования

бя" (self-redirect), а также при проставлении значения атрибута action тега <form> на странице, которую выдает сценарий при запуске без параметров (для того чтобы не привязываться к конкретному имени сценария).

□ request_method

Метод, который применяет пользователь при передаче данных (мы рассматриваем только get и post, хотя существуют и другие методы). Надо заметить, что грамотно составленный сценарий должен сам определять на основе этой переменной, какой метод задействует пользователь, и принимать данные из соответствующего источника, а не рассчитывать, что передача будет осуществляться, например, только методом post. Впрочем, все PHP-сценарии так и устроены.

□ query^string

Параметры, которые в URL указаны после вопросительного знака. Напомню, что они доступны как при методе get, так и при методе post (если в последнем случае они были определены в атрибуте action тега <form>).

□ content_length '

Количество байтов данных, присланных пользователем. Эту переменную необходимо анализировать, если вы занимаетесь приемом и обработкой роэт-формы.

Передача параметров методом GET

Тут все просто. Все параметры передаются единой строкой (а именно точно такой же, какая была задана в URL после ?) в переменной query_string. Единственная проблема — все данные поступят URL-кодированными. Так что нам понадобится функция декодирования. Но это отдельная тема, пока мы не будем ее касаться.

Для того чтобы узнать значения полученных переменных в С, нужно воспользоваться функцией getenvo. В листинге 3.2 приведен пример сценария на С, который это обеспечивает.

| Листинг 3.2. Файл c/env.c

// Работа с переменными окружения

#include <stdio.h> // Включаем функции ввода/вывода #include <stdlib.h> // Включаем функцию getenv()

void main(void) {

// получаем значение переменной окружения REMOTE_ADDR char *RemoteAddr = getenv("REMOTE_ADDR"); // ... и еще QUERY_STRING

char *QueryString = getenv("QOERY_STRING"); // печатаем заголовок

printf("Content-type: text/html\n\n") ; // печатаем документ printf ("<htmlxbody>") ;

printf("<Ь1>Здравствуйте. Мы знаем о Вас Bce!</hl>"); printf("Ваш IP-адрес: %s<br>",RemoteAddr);

printf("Вот параметры, которые Вы указали: %s", QueryString) ; printf ("</body></html>");

Гпава 3. CGI изнутри

85

Откомпилируем сценарий и поместим его в CGI-каталог. Теперь в адресной строке введем:

http://www.myhost.com/cgi-bin/script.cgi?a=l&b=2

Мы получим примерно такой документ:

Здравствуйте. Мы знаем о Вас все!

Ваш ip-адрес: 192.168.1.23

Вот параметры, которые Вы указали: а=1&Ь=2

Передача параметров методом POST

В отличие от метода get, здесь параметры передаются сценарию не через переменные окружения, а через стандартный поток ввода (в С он называется stdin). То есть программа должна работать так, будто никакого сервера не существует, а она читает данные, вводимые пользователем с клавиатуры. (Конечно, на самом деле никакой клавиатуры нет и быть не может, а заправляет всем сервер, который "изображает из себя" клавиатуру.)

щшшшшшт

Следует заметить очень важную деталь: использование метода post вовсе не означает, что не был применен также и метод get. Иными словами, метод post подразумевает также возможность передачи данных через URL-строку. Эти данные будут, как обычно, помещены в переменную окружения query_string.

Но как же узнать, сколько именно данных переслал пользователь методом post? До каких пор нам читать входной поток? Для этого служит переменная окружения content_length, в которой хранится строка с десятичным представлением числа переданных байтов данных (разумеется, перед использованием ее надо перевести в обычное число).

Модифицируем предыдущий пример так, чтобы он принимал post-данные, а также выводил и get-информацию, если она задана (листинг 3.3).

i Листинг 3.3. Файл c/post.c

// Получение данных POST #include <stdio.h> #include <stdlib.h>

void main(void) {

// извлекаем значения переменных окружения

char *RemoteAddr = getenv("REMOTE_ADDR");

char *ContentLength = getenv("CONTENT_LENGTH");

char *QueryString = getenv ("QUERY__STRING") ;

// вычисляем длину данных — переводим строку в число

int NumBytes = atoi(ContentLength);

// выделяем в свободной памяти буфер нужного размера char *Data = (char *)malloc(NumBytes + 1);




  Hostland.Ru

 «Бесплатный хостинг Hostland.Su» © 2006