ABC skryptów CGI

Wstecz Dalej

CGI i formularze

Bodaj najbardziej klasycznym zastosowaniem skryptów CGI jest obsługa danych pochodzących z formularzy zamieszczanych na stronach WWW. Praktycznie z każdym takim formularzem związany jest jakiś skrypt - jego adres podaje się w parametrze ACTION= znacznika
. Po kliknięciu na przycisk "Wyślij" w formularzu przeglądarka przesyła wprowadzone dane do serwera, który z kolei przekazuje je uruchomionemu skryptowi.

Dane przesyłane z formularza mają następującą postać:

     nazwa1=wartość1&nazwa2=wartość2&nazwa3=wartość3 ...
gdzie nazwa1, nazwa2 itd. są nazwami poszczególnych pól formularza (podawanymi w parametrach NAME= odpowiednich znaczników w kodzie HTML formularza), zaś wartość1, wartość2 itd. - wartościami, które zostały przez użytkownika wpisane w te pola. Wartości te kodowane są przy użyciu kodowania URL (por. rozdział "Wywoływanie skryptów z parametrami"); spacje zamieniane są na znak "+", zaś inne znaki specjalne (w tym "=" i "&") na szesnastkowy zapis postaci %nn. Jeżeli zatem przykładowy formularz, którego kod przedstawiony jest poniżej:

     <form action="http://www.serwer.com/katalog/skrypt.cgi" method="get">
     Nazwisko: <input type="text" name="nazwisko"><p>
     Adres e-mail: <input type="text" name="email"><p>
     Płeć: <input type="radio" name="plec" value="k"> Kobieta
     <input type="radio" name="plec" value="m"> Mężczyzna<p>
     <input type="submit" value="OK">
     </form>
zostanie wypełniony jak na rys.9, to po kliknięciu przycisku "OK" do serwera zostanie wysłany ciąg danych postaci:

     nazwisko=Jaros%B3aw+Rafa&email=raj@inf.wsp.krakow.pl&plec=m
Istnieją dwie zasadnicze metody przekazywania serwerowi danych z formularza - GET i POST. O użytej metodzie decyduje wartość parametru METHOD= w znaczniku . W przypadku metody GET (tak jak w powyższym formularzu) cały powyższy ciąg znaków zostanie przekazany skryptowi jako wartość zmiennej środowiskowej QUERY_STRING (por. rozdział "Wywoływanie skryptów z parametrami"). Jeżeli natomiast skrypt zostanie wywołany z użyciem metody POST, wówczas zmienna QUERY_STRING pozostanie pusta, zaś powyższy ciąg znaków zostanie przekazany na standardowe wejście (!) skryptu, skąd musimy go odczytać. W takim przypadku ustawione zostaną dwie dodatkowe zmienne środowiskowe, CONTENT_TYPE i CONTENT_LENGTH. Pierwsza z nich zawierać będzie wartość "application/x-www-form-urlencoded", natomiast druga, bardzo istotna - liczbę znaków, które należy odczytać ze standardowego wejścia.

Na ogół metody GET używa się w przypadku prostych formularzy z niewielką ilością danych, zaś bardziej skomplikowane obsługuje się przy użyciu metody POST (w przypadku metody GET mogą wystąpić problemy ze zbyt dużą jej długością). W obydwu jednak przypadkach skrypt musi wydzielić z otrzymanego ciągu znaków wartości poszczególnych pól formularza i zdekodować je, co może być dość skomplikowane. Na szczęście w modułach bibliotecznych języka Perl znajduje się funkcja, która automatycznie wykonuje wszystkie operacje związane z odczytaniem i zdekodowaniem danych z formularza - i to niezależnie od tego, czy zastosowana została metoda GET, czy POST. Wystarczy tylko umieścić w programie wiersz:

     use CGI;
sygnalizujący zamiar skorzystania z odpowiedniego modułu bibliotecznego, a następnie wywołać funkcję

     CGI::ReadParse(*form);
aby utworzyć tablicę asocjacyjną o nazwie form (można oczywiście użyć dowolnej innej nazwy), której elementami będą wartości poszczególnych pól formularza, a indeksami - nazwy tych pól. W przypadku zatem naszego przykładowego formularza poszczególne elementy tej tablicy będą następujące:

     $form{'nazwisko'}
będzie zawierać tekst
"Jarosław Rafa"
     $form{'email'}
-
"raj@inf.wsp.krakow.pl"
   i $form{'plec'}
-
"m"
Oczywiście z tymi danymi trzeba "coś" zrobić. Przedstawiony formularz może służyć np. do zapisywania się na e-mailową listę wysyłkową. Załóżmy, że zapisanie użytkownika na listę polega technicznie na dopisaniu jego nazwiska i adresu e-mail do pliku, z którego korzysta program rozsyłający informacje:

     #!/usr/bin/perl
     use CGI;
     CGI::ReadParse(*form);

     print "Content-type: text/html; charset=iso-8859-2\n\n";
     print "<html>\n<head><title>Wpis na listę</title></head>\n";
     print "<body>\n";

     if ($form{'nazwisko'} && $form{'email'} =~ /[^ ]+@[^ ]+\.[^ ]+/) {

        open (LISTA,">>lista.dat");
        print LISTA "$form{'nazwisko'} <$form{'email'}>\n";
        close (LISTA);

        print "<h1 align=\"center\">$form{'nazwisko'}</h1>\n";
        if ($form{'plec'} eq "k") {
           print "Zostałaś dopisana";
        } else {
           print "Zostałeś dopisany";
        }
        print " do listy subskrybentów naszego biuletynu.<p>\n";
        print "Spodziewaj się wkrótce e-maila w swojej skrzynce!\n";

     } else {

        print "<h1 align=\"center\">Błąd !</h1>\n";
        print "Formularz nie został wypełniony prawidłowo.<p>\n";
        print "Kliknij przycisk Wstecz w przeglądarce i spróbuj ponownie.\n";

     }
     print "</body>\n</html>\n";
Bezpośrednio po wypisaniu nagłówka i początku kodu strony znajduje się instrukcja if sprawdzająca poprawność wprowadzonych danych (każdy skrypt przyjmujący dane z formularza powinien sprawdzać ich poprawność). Warunek w tej instrukcji jest połączeniem dwóch warunków, z których pierwszy składa się z samej zmiennej $form{'nazwisko'}. Warunek taki jest prawdziwy wówczas, gdy wartość zmiennej jest niepusta, czyli gdy w pole "nazwisko" został wpisany jakikolwiek tekst. Drugi warunek wykorzystuje perlowy operator dopasowania do wzorca (=~) do sprawdzenia poprawności adresu e-mail. Zmienna $form{'email'} musi zawierać znak "@", przed którym musi występować przynajmniej jeden znak różny od spacji, zaś po nim - przynajmniej dwa takie znaki, pomiędzy którymi znajduje się przynajmniej jedna kropka (zapis "\." we wzorcu oznacza kropkę, zaś "[^ ]+" - przynajmniej jeden znak różny od spacji).

Wprowadzenie poprawnych danych - np. takich jak przedstawione powyżej - spowoduje dopisanie do pliku lista.dat (oczywiście plik ten musi mieć prawa dostępu analogiczne do pliku licznik.dat z poprzedniego przykładu) wiersza postaci

     Jarosław Rafa <raj@inf.wsp.krakow.pl>
oraz wyświetlenie w przeglądarce komunikatu potwierdzającego ten fakt (rys.10). "Kosmetycznym" elementem jest wykorzystanie instrukcji if do uzyskania odpowiedniej formy gramatycznej komunikatu w zależności od płci subskrybenta - wykorzystywane jest do tego pole plec formularza, które poza tym nie służy do niczego innego. Jeżeli natomiast wprowadzone dane nie były poprawne, wykonywane są polecenia z części else instrukcji if, wypisujące komunikat o błędzie.

Jako że znaczniki HTML bardzo często zawierają znaki cudzysłowu, warto zwrócić uwagę na pierwsze instrukcje print w każdej z części instrukcji if, wypisujące takie właśnie znaczniki (<h1 align="center">). Aby umieścić znaki cudzysłowu wewnątrz stałej tekstowej, która sama ujęta jest w cudzysłowy, musimy poprzedzić je znakiem "\" (backslash).


Wstecz Dalej

Jarosław Rafa 2000. Tekst udostępniony na licencji Creative Commons (uznanie autorstwa - użycie niekomercyjne - bez utworów zależnych). Kliknij tutaj, aby dowiedzieć się, co to oznacza i co możesz z tym tekstem zrobić. W razie jakichkolwiek wątpliwości licencyjnych bądź w celu uzyskania zgody na rozpowszechnianie wykraczające poza warunki licencji proszę o kontakt e-mailem: raj@ap.krakow.pl.

Wersja HTML opracowana 11.10.2000.


Powrót do spisu treści Statystyka