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

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


86

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

// читаем данные из стандартного потока ввода

fread(Data, 1, NumBytes, stdin);

// добавляем нулевой код в конец строки

// (в С нулевой код сигнализирует о конце строки)

Data[NumBytes] = 0;"

// выводим заголовок

printf("Content-type: text/html\n\n"); // выводим документ printf("<html><body>");

printf("<п1>3дравствуйте. Мы знаем о Вас все!</hl>");

printf("Ваш IP-адрес: %s<br>",RemoteAddr) ;

printf("Количество байтов данных: %d<br>",NumBytes);

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

printf("А вот то, что мы получили через URL: %s",QueryString);

printf("</body></html>");

Откомпилируем этот сценарий и запишем результат под именем script.cgi в каталог, видимый извне как /cgi-bin/. Откроем в браузере следующий HTML-файл с формой из листинга 3.4.

! Листинг 3.4. Файл postform.htm

<!— POST-форма —> <htmlxbody>

<form action=/cgi-bin/script.cgi?param=value method=post> Namel: <input type=text name="namel"Xbr> Name2: <input type=text name="name2"xbr> <input .type=submit уа1ие="3апустить сценарий! "> </form>

</bodyx/html>

Теперь, если набрать в полях ввода какой-нибудь текст и нажать кнопку, получим HTML-страницу, сгенерированную сценарием, например, следующего содержания:

Здравствуйте. Мы знаем о Вас все! Ваш IP-адрес: 136.234.54.2 Количество байтов данных: 23

Вот параметры, которые Вы указали: namel=Vasyasname2=Petya А вот то, что мы получили через URL: param=value

Как можно заметить, обработка метода post устроена сложнее, чем get. Тем не менее метод post используется чаще, особенно если нужно передавать большие объемы данных или закачивать файл на сервер (эта возможность также поддерживается протоколом HTTP и HTML).

Расшифровка URL-кодированных данных

Пожалуй, ни один сценарий не обходится без функции расшифровки URL-кодированных данных. И это совсем не удивительно. Если бы в предыдущем примере

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

87

мы ввели параметры, содержащие, например, буквы кириллицы, то сценарий получил бы их не в "нормальном" виде, а в URL-закодированном. Радует только то, что такую функцию нужно написать один раз, а дальше можно пользоваться ей по мере необходимости.

Как уже упоминалось, кодирование заключается в том, что некоторые неалфавитно-цифровые символы (в том числе и "русские" буквы, которые тоже считаются неалфавитными) преобразуются в форму %хх, где хх — код символа в шестнадцатеричной системе счисления. Далее представлена функция на С (листинг 3.5), которая умеет декодировать подобные данные и приводить их к нормальному представлению.

Пожалуйста, не путайте URL-кодирование и HTML-кодирование! Это совершенно разные процессы: после первого мы получаем строки вида %xx%yy%zz, а после второго — вида sit; &amp; squot.

Мы не можем сначала все данные (например, полученные из стандартного потока ввода) декодировать, а уж потом работать с ними (в частности, разбивать по месту вхождения символов & и =). Действительно, вдруг после перекодировки появятся символы & и =, которые могут быть введены пользователем? Как мы тогда узнаем, разделяют ли они параметры или просто набраны с клавиатуры? Очевидно, никак. Поэтому такой способ нам не подходит, и придется работать с каждым значением отдельно, уже после разделения строки на части.

Итак, приходим к следующему алгоритму: сначала разбиваем строку параметров на блоки (параметр^значение), затем из каждого блока выделяем имя параметра- и его значение (разделенные символом =), а уж потом для них вызываем функцию перекодировки.

| Листинг 3.5. Файл c/urldecode.c

// Функция URL-декодирования.

// Функция преобразует строку данных st в нормальное представление.

// Результат помещается в ту же строку, что была передана в параметрах.

void UrlDecode(char *st) {

char *p=st; // указывает на текущий символ строки

char hex[3]; // временный буфер для хранения %ХХ

int code; // преобразованный код

// запускаем цикл, пока не кончится строка (т. е. пока // не появится символ с кодом 0, см. ниже) do {

// Если это %-код ...

if(*st =='%') { // тогда копируем его во временный буфер hex[0]=*(++st); hex[1]=*(++st); hex[2]=0; // переводим его в число sscanf(hex,"%Х",scode); //и записываем обратно в строку *р++=(char)code;

// указатель р всегда отмечает то место в строке, в которое // будет помещен очередной декодированный символ

}




  Hostland.Ru

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