Viena populiariausių CGI programų pasauliniame Internet tinkle - svečių knyga (guestbook). Tai yra paprasčiausia forma, kuri leidžia tinklapio ar svetainės lankytojams palikti atsiliepimus bei informaciją apie save to tinklapio ar svetainės šeimininkui, o taip pat kitiems lankytojams. Informacija patalpinama į failą, kurį gali peržiūrinėti kiekvienas. Tai elektroninis variantas svečių knygos, su kuria turbūt beveik visiems teko susidurti realiame gyvenime - muziejuose, memorialuose, kitose įvairiausių žmonių lankomose vietose.
Kurdami svečių knygą internete, turime išskirti šiuos etapus:
Programa prasideda:
#!/usr/local/bin/perl
$webmaster = "virga\@soften\.ktu\.lt";
$method = $ENV{'REQUEST_METHOD'};
$script = $ENV{'SCRIPT_NAME'};
$query = $ENV{'QUERY_STRING'};$document_root = "/home/staff/Virga/public_html";
$guest_file = "/CGI_knyga/guestbook.html";
$root_url = "http://www.soften.ktu.lt/~virga";
$guest_url = $root_url . $guest_file;
$full_path = $document_root . $guest_file;
Šiame inicializavimo kode document_root kintamasis yra katalogas, kuriame yra jūsų HTML failai. Guest_file kintamajo reikšmė yra reliatyvus kelias iki svečių knygos failo, imant šakniniu katalogą, nurodytą document_root kintamajame. O full_path yra pilnas kelias iki svečių knygos failo. Kintamasis root_url yra pilnas jūsų svetainės internetinis adresas. O guest_url yra pilnas internetinis adresas, pagal kurį pasiekiamas svečių knygos failas. Labai svarbu atskirti pilną ir reliatyvų kelią, kaip pamatysime toliau nagrinėdami programą.
$exclusive_lock = 2;
$unlock = 8;
Failo užrakinimo ir atrakinimo reikšmės yra saugomos atitinkamai exclusive_lock ir unlock kintamuosiuose.
if ($method eq "GET") {
if ($query eq "add") {
Ši programa parašyta truputį kitaip nei kitos programos, kurias sutikote
šiojeknygoje. Pirmiausia pažiūrėkime, kaip į programą ( Kaip matote, programa yra labai visapusiška. Ji atlieka visus veiksmus su svečių
knyga. Visiškai nesunku yra suskaidyti programą į jos sudėtines dalis: HTML formą,
programą svečių knygos išvedimui (nebūtina), ir programą iš formos gautai
informacijai dekoduoti. Bet kuris atvejis turi savų privalumų. Visų veiksmų apjungimas
vienoje programoje garantuoja, kad visi programos komponentai yra vienoje vietoje ir
failai negali būti atsitiktinai patalpinti ne ten. Iš kitos pusės, atskyrimas
užtikrina kiekvieno svečių knygos komponento savarankiškumą - visi jie gali būti
modifikuojami nerizikuojant pažeisti kitų komponentų vientisumo. Tad pasirinkimas
priklauso tik nuo to, kas konkrečiam asmeniui, kuriančiam svečių knygą, yra svarbiau.
$date_time = &get_date_time(); Paprogramė get_date_time grąžina einamąją datą ir laiką. &MIME_header ("text/html", "CGI puslapio svečių knyga"); Paprogramė MIME_header išveda nurodytą MIME headerį ir suteikia dokumentui
pavadinimą, kurį vartotojas perdavė kaip argumentą. Vienintelė priežastis, kodėl
čia naudojama paprogramė - tai noras padaryti programą kuo kompaktiškesne. print <<End_Of_Guestbook_Form; Tai yra svečių knygos CGI skriptas, leidžiantis žmonėms palikti šiame
puslapyje atsiliepimus, kuriuos galės matyti ir kiti lankytojai. Prašome įvesti visą
reikiamą informaciją, <B>ir</B> jei jūs turite savo tinklapį, įveskite jo
adresą, kad būtų galima sukurti hipertekstinę nuorodą. Pirmiausia yra išvedamas pasisveikinimas kartu su einamąja data ir laiku. (Jūs
negalite kviesti paprogramių print "blokų" viduje, todėl get_date_time paprogramė
datos ir laiko nustatymui buvo iššaukta anksčiau, o jos grąžinta reikšmė priskirta
kintamajam date_time.). <FORM METHOD="POST"> End_Of_Guestbook_Form Kaip matote, nėra nurodytas ACTION atributas <FORM> aprašyme. Kai ACTION
atributas praleistas, naršyklė pagal nutylėjimą persiunčia užpildytą formą šitai
pačiai CGI programai. METHOD priskirta reikšmė POST - kaip pamatysite vėliau, pagal
tai svečių knygos programa sužinos, kad forma užpildyta. Čia yra išvedami įvairūs sudarantys formą elementai. Komanda <PRE> išlygina
tekstinius laukus. Štai taip užpildytą formą atvaizduoja naršyklė Inernet Explorer4:
Jeigu kreipinyje į programą nebuvo užklausos parametro, yra išvedamas svečių
knygos duomenų failas. } else { if (open(GUESTBOOK, "<" . $full_path) ) { flock (GUESTBOOK, $exclusive_lock); Kintamojo full_path reikšmė yra pilnas kelias iki svečių knygos failo.
Pagrindinė priežastis, kodėl reliatyvus kelias ir pilnas kelias iki failo yra saugomi
atskirai, yra ta, kad hipertekstiniams tikslams reikalingas reliatyvus kelias, o failui
atidaryti reikalingas pilnas kelias. Prieš atidarant bet kokį failą, derėtų
patikrinti, ar tas failas gali būti atidarytas. &MIME_header ("text/html", "Tai yra mūsų svečių
knyga!"); while (<GUESTBOOK>) { flock (GUESTBOOK, $unlock); Ciklas eina per visas failo eilutes ir standartiškai išveda jas: } else { &return_error (500, "Svečių knygos failo klaida", "Negaliu
nuskaityti svečių knygos failo [$full_path]."); } } Jeigu atidarant failą iškilo kokios nors problemos, kliento programai (naršyklei)
perduodamas pranešimas apie klaidą. Paprogramė return_error yra tokia pati,
kokia buvo pateikta 4 skyriuje, Prisimenate "add" formą, kurioje <FORM> aprašyme buvo nurodytas POST
metodas? } elsif ($method eq "POST") { if (open(GUESTBOOK, ">>" . $full_path) ) { flock (GUESTBOOK, $exclusive_lock); $date_time = &get_date_time(); Dabar įtrauksime naują įrašą į svečių knygą. Pirmiausia programa patikrina, ar
gali rašyti į svečių knygos failą. Jeigu neįvyksta klaida, failas atidaromas
papildymo režimui ir užrakinamas, kad nebūtų prieinamas jokiems kitiems procesams.
Formos informacija yra dekoduojama ir patalpinama į asociatyvų masyvą FORM. Paprogramė
parse_form_data šioje programoje yra šiek tiek kitokia, nei ta, kurią sutikome 4
skyriuje; ji netikrina GET užklausų, kadangi programa naudoja ją tik POST metodui. $FORM{'name'} =
"Anonimas" if
!$FORM{'name'}; Aukščiau matote konstrukciją, kurios galbūt neteko sutikti anksčiau. Tai
paprastesnis užrašymo būdas tokių išraiškų: if (!$FORM{'name'}) { Kitaip sakant, formos kintamieji name ir from yra patikrinami, ar yra
užpildyti. Jei laukai tušti, jiems priskiriamos reikšmės pagal nutylėjimą. $FORM{'comments'} =~ s/\n/<BR>/g; Informacija, kurią lankytojas įvedė <TEXTAREA> lauke yra saugoma comments.Visi
naujos eilutės simboliai pakeičiami HTML perėjimo žymėmis. Tai užtikrina, kad
informacija bus išvedama teisingai. Atkreipkite dėmesį, kad jei vartotojas kaip
komentarų dalį įveda HTML kodą (arba SSI direktyvas) , kodas bus interpretuojamas.
Taigali būti pavojinga. Žiūrėkite skyrių "Sąsajos (gateways), duomenų
bazės ir paieškos/indeksavimo priemonės", kuriame pateiktas būdas, kaip
"išvengti" HTML kodo. print GUESTBOOK <<End_Of_Write; <P> End_Of_Write Lankytojo vardas, internetinės mašinos vardas ir komentarai, kartu su einamąja data
ir laiku, yra išvedami i svečių knygos failą. if ($FORM{'www'} and !($FORM{'www'} eq "http://")) { print GUESTBOOK <<End_of_Web_Address; <P> End_of_Web_Address } print GUESTBOOK "<P><HR>"; Jei vartotojas pateikė HTTP adresą, pastarasis taip pat bus išvestas. flock (GUESTBOOK, $unlock); Failas atrakinamas ir uždaromas. Labai svarbu nepamiršti atrakinti ir uždaryti
svečių knygos failą, norint užtikrinti priėjimą prie jo kitiems žmonėms. Galiausiai, jei viskas tvarkoje, išvedamas padėkos pranešimas ir nuoroda į svečių
knygą, kad lankytojas galėtų ją peržiūrėti. &MIME_header ("text/html", "Ačiū!"); print <<End_of_Thanks; Dėkojame už apsilankymą mūsų svečių knygoje. Jeigu norite ją peržiūrėti,
paspauskite <A HREF="$guest_url">čia</A> (tikras svečių knygos
HTML failas), arba <A HREF="$script">čia</A> (svečių knygos
skriptas be užklausos parametro). End_of_Thanks Jei programa negali rašyti į svečių knygos failą, generuojamas pranešimas apie
klaidą. Kitoks pranešimas yra generuojamas, jeigu naudojamas netinkamas kreipimosi į
CGI programą metodas. } else { &return_error (500, "Svečių knygos failo klaida", "Negaliu
rašyti į svečių knygos failą [$full_path]."); } } else { &return_error (500, "Serverio klaida", "Serveris naudoja
nežinomą metodą"); } exit(0); Paprogramė MIME_header išveda MIME headerį, o taip pat dokumento pavadinimą
ir antraštę. Jei trečiasis argumentas nenurodytas, pavadinimas ir antraštė bus tokie
patys. sub MIME_header local ($mime_type, $title_string, $header) = @_; if (!$header) { $header = $title_string; } print "Content-type: ", $mime_type, "\n\n"; } Paprogramė get_date_time grąžina einamąją datą ir laiką. sub get_date_time local ($months, $weekdays, $ampm, $timestring); $months = "Sausio/Vasario/Kovo/Balandžio/Gegužės/" . $weekdays = "Sekmadienis/Pirmadienis/Antradienis/" . local ($sec, $min, $hour, $day, $nmonth, $year, Funkcija localtime grąžina devynių elementų masyvą, kuris sudarytas iš
laiko, datos ir esamos laiko zonos. Ankstesniuose pavyzdžiuose mes naudojome tik
pirmuosius tris šio masyvo elementus; šiame pavyzdyje mes priskiriame visus devynis. $year += 1900; $week = (split("/", $weekdays))[$wday]; Funkcijos localtime grąžinamos skaitmeninės savaitės dienos (wday) ir
mėnesio (nmonth) reikšmės yra skaičiuojamos nuo nulio. Kintamajam week yra
priskiriamas savaitės dienos pavadinimas paimant iš kintamojo weekdays eilutę,
atitinkančią skaitmeninę savaitės dienos reikšmę. Toks pats veiksmas pakartojamas
nustatant mėnesio pavadinimą. $time_string = sprintf("%s m., %s %s d., %s - %02d:%02d:%02d", $year,
$month, $day, $week, $hour, $min, $sec); return ($time_string); } Taigi, paprogramė get_date_time grąžins datą tokia forma: 1998 m., Lapkričio 25 d., Trečiadienis - 15:45:02 Paskutinė paprogramė svečių knygos tvarkymo programoje yra parse_form_data. sub parse_form_data local (*FORM_DATA) = @_; local ( $request_method, $post_info, @key_value_pairs, $key_value, $key, $value);
read (STDIN, $post_info, $ENV{'CONTENT_LENGTH'}); @key_value_pairs = split (/&/, $post_info); foreach $key_value (@key_value_pairs) { ($key, $value) = split (/=/, $key_value); if (defined($FORM_DATA{$key})) { $FORM_DATA{$key} = join ("\0", $FORM_DATA{$key}, $value); } else { $FORM_DATA{$key} = $value; } } } Kaip jau buvo minėta anksčiau, paprogramė netikrina GET užklausų. Nėra poreikio
tai daryti, kadangi tai atliekama pagrindinėje programoje.
<P>
Dabar yra: $date_time
<HR>
<PRE>
<EM>Pilnas vardas</EM>:<INPUT TYPE="text"
NAME="name" SIZE=40>
<EM>E-mail</EM>:<INPUT TYPE="text" NAME="from"
SIZE=40>
<EM>WWW tinklapis</EM>:<INPUT TYPE="text"
NAME="www" value="http://" SIZE=40>
</PRE>
<P>
<EM>Įveskite informaciją, kurią norite pateikti:</EM><BR>
<TEXTAREA ROWS=3 COLS=60 NAME="comments"></TEXTAREA><P>
<INPUT TYPE="submit" VALUE="Įtraukti į svečių knygą">
<INPUT TYPE="reset" VALUE="Išvalyti
informaciją"><BR>
<P>
</FORM>
<HR>
print;
}
close(GUESTBOOK);
Štai čia ši forma yra apdorojama. Jeigu užklausos metodas yra POST, tai reiškia, kad
vartotojas užpildė formą ir pateikė ją atgal šiai programai.
&parse_form_data (*FORM);
$FORM{'from'} = $ENV{'REMOTE_HOST'} if !$FORM{'from'};
$FORM{'name'} = "Anonimas";
}
if (!$FORM{'from'}) {
$FORM{'from'} = $ENV{'REMOTE_HOST'};
}
<B>$date_time:</B><BR>
Žinutę atsiuntė <EM>$FORM{'name'}</EM> iš
<EM>$FORM{'from'}</EM>:
<P>
$FORM{'comments'}
$FORM{'name'} taip pat turi tinklapį:
<A HREF="$FORM{'www'}">$FORM{'www'}</A>
close(GUESTBOOK);
{
print "<HTML>", "\n";
print "<HEAD><TITLE>", $title_string,
"</TITLE></HEAD>", "\n";
print "<BODY>", "\n";
print "<H1>", $header, "</H1>";
print "<HR>";
{
"Birželio/Liepos/Rugpjūčio/Rugsėjo/" .
"Spalio/Lapkričio/Gruodžio";
"Trečiadienis/Ketvirtadienis/" .
"Penktadienis/Šeštadienis";
$wday, $yday, $isdst) =
localtime(time);
$month = (split("/", $months))[$nmonth];
{
$value =~ tr/+/ /;
$value =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;