Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 [ 226 ] 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

$States{$page>->(); # Вызвать нужную подпрограмму > else {

no such page(),

На каждой странице найдется несколько устойчивых элементов. Например, страница для заказа футболок должна сохранить количество заказанных товаров, даже если пользователь переходит на страницу для заказа кроссовок. Для этого подпрограмма, генерирующая страницу, вызывается с параметром, который определяет, является ли данная страница активной. Если страница не является активной, возвращаются лищь значения скрытых полей для любых устойчивых данных:

while (($state, $sub) = each %States) { $sub->( $page eq $state );

Оператор сравнения eq возвращает true, если страница является активной, и false в противном случае. Подпрограмма, генерирующая страницу, принимает следующий вид:

sub t shirt {

my Sactive = shift;

unless (Sactive) {

print hidden(size"), hidden(color"); return,

>

print pCYou want to buy a t-shirf");

print pCSize ", popup menu("size", [ qw(XL L M S XS) ])), print pCColor ", popup menu("color", [ qw(Black White) ]));

print p( to page(Shoes"), to page( Checkout) ),

Поскольку все подпрограммы генерируют HTML-код, перед вызовом необходимо вывести заголовок HTTP и начать HTML-документ и форму. Это позволит использовать стандартные колонтитулы для всех стращщ, если мы захотим. Следующий фрагмент предполагает, что у нас имеются процедуры standarcl header и standard footer для вывода верхних и нижних колонтитулов страниц:

print header(Program Title"), begin html(), print standard header(), begin form(); while ((Sstate, $sub) = each %States) { $sub->( $page eq $state ),

print standard footer(), end form(), end html().

Кодирование цены в форме будет ошибкой. Вычисляйте цены на основании значений скрытых элементов и как можно чаще проверяйте информацию. Например, сравнение со списком существующих продуктов позволяет отбросить явно неразумные заказы.



Скрытые данные обладают большими возможностями, чем cookies, поскольку вы не можете твердо рассчитывать на поддержку cookies или на то, что броузер согласится принять их. Более полная информация приведена в рецепте 19.10.

В конце главы приведена программа chemiserie - простейшее приложение для обслуживания электронного магазина.

> Смотри также-

Документация по стандартному модулю CGI.

19.13. Сохранение формы в файле или канале

Проблема

Сценарий CGI должен сохранить все содержимое формы в файле или передать его в канал.

Решение

Для сохранения формы воспользуйтесь функцией save paranieters или методом save модуля CGI; их параметром является файловый манипулятор. Сохранение в файле выполняется так:

# Сначала открыть и монопольно заблокировать файл

open(FH, "»/tmp/formlog") or die "cant append to formlog: $!"; flock(FH, 2) or die "cant flock formlog- $!";

tt Используется процедурный интерфейс use CGI qw(:standard);

save parameters(«FH); #CGI::save

# Используется объектный интерфейс use CGI;

Squery = CGI->new(); $query->save(.FH);

close(FH) or die "cant close formlog: $";

Или форма сохраняется в канале - например, соединенном с процессом sendmail:

use CGI qw(:standard);

open(MAIL, "l/usr/lib/sendmail -oi -t")

or die "cant fork sendmail: $!";

print MAIL «EOF; From: $0 (your cgi script) To: hisname\@hishost.com Subject: mailed form submission



19.13. Сохранение формы в файле или канале 697

save parameters( «МАИ);

close(MAIL) or die "cant close sendmail: $!";

Комментарий

Иногда данные формы сохраняются для последующего использования. Функция save parameters и метод save модуля CGI.pm записывают параметры формы в открытый манипулятор. Манипулятор может быть связан с открытым файлом (желательно - открытым в режиме дополнения и заблокированным, как в рещении) или каналом, другой конец которого подключен к почтовой программе.

Данные сохраняются в файле в виде пар пере«енная=эиачеиие, служебные символы оформляются по правилам URL. Записи разделяются строками, состоящими из единственного символа =. Как правило, чтение осуществляется методом CGI->new с аргументом-манипулятором, что обеспечивает автоматическое восстановление служебных символов (см. ниже).

Если вы хотите перед сохранением включить в запрос дополнительную информацию, вызовите функцию param (или метод, если используется объектно-ориентированный интерфейс) с несколькими аргументами и установите нужное значение (или значения) параметра формы. Например, текущее время и состояние окружения сохраняется следующим образом:

param(" timestamp", scalar localtime); param(" environs", %ENV);

После сохранения формы в файле дальнейшая работа с ней ведется через объектно-ориентированный интерфейс.

Чтобы загрузить объект-запрос из файлового манипулятора, вызовите метод new с аргументом-манипулятором. При каждом вызове возвращается законченная форма. При достижении конца файла будет возвращена форма, не имеющая параметров. Следующий фрагмент показывает, как это делается. Он накапливает сумму всех параметров "items requested", но лишь в том случае, если форма поступила не с сайтаperl.com. Напомним, что параметры environs и timestamp были добавлены при записи файла.

use CGI;

open(F0RMS, "< /tmp/formlog") or die "cant read formlog: $!";

flock(FORMS, 1) or die "cant lock formlog: $!";

while (Squery = CGI->new(.FORMS)) {

last unless $query->param(); # Признак конца файла

%his env = $query->param(.environs);

Scount += $query->param(items requested)

unless $his env{REM0TE H0ST} = /("\,)perl\.com$/

>

print "Total orders: $count\n";

Как всегда при создании файлов в сценариях CGI, важную роль играют права доступа и права владельца файла.

> Смотри также -

Рецепты 18.3; 19.3.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 [ 226 ] 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242