ABC skryptów CGI

Wstecz Dalej

Najprostsze skrypty

W rozdziale "Między serwerem a skryptem" omówiony został przykład najprostszego skryptu CGI, którego wynik wykonania przedstawiony jest na rys.2. Skrypt ten zapisany w języku Perl może mieć np. taką postać (wszystkie omawiane w tym poradniku skrypty znaleźć można pod adresem http://www.wsp.krakow.pl/papers/abc_cgi/):

     #!/usr/bin/perl
     print "Content-type: text/html\n\n";
     print "<html>\n<head><title>Skrypt</title></head>\n";
     print "<body>\n<h1>Jestem skryptem</h1>\n";
     print "</body>\n</html>\n";
Skrypt składa się zatem po prostu z ciągu instrukcji print, wypisujących na standardowe wyjście nagłówek Content-type: text/html, a następnie kod HTML strony. Kombinacja znaków "\n" w perlowej instrukcji print oznacza przejście do nowego wiersza - instrukcja ta nigdy nie przechodzi do nowego wiersza "sama z siebie", a więc każde miejsce, gdzie powinno nastąpić takie przejście, trzeba jawnie zaznaczyć. Zauważmy, że dzięki umieszczeniu podwójnej sekwencji "\n\n" na końcu pierwszej instrukcji uzyskujemy pusty wiersz niezbędny do oddzielenia nagłówka od treści strony.

Ten sam efekt można uzyskać nieco prościej, używając innej postaci instrukcji print:

     #!/usr/bin/perl
     print <<"KONIEC";
     Content-type: text/html

     <html>
     <head><title>Skrypt</title></head>
     <body>
     <h1>Jestem skryptem</h1>
     </body>
     </html>
     KONIEC
Ta forma instrukcji przepisuje na standardowe wyjście wszystkie następujące po niej wiersze skryptu, aż do napotkania wiersza rozpoczynającego się od tekstu podanego po znakach "<<", czyli słowa "KONIEC".

Rzecz jasna skrypt taki nie ma większego sensu, gdyż wypisywana przezeń treść jest niezmienna - jego rolę mógłby zatem równie dobrze spełniać umieszczony na serwerze zwykły plik HTML. Z reguły skrypty CGI wykorzystuje się do generowania stron, których treść zmienia się przy każdym uruchomieniu skryptu, tak jak w poniższym przykładzie, podającym aktualny czas systemowy na serwerze:

     #!/usr/bin/perl
     @miesiace = ("stycznia", "lutego", "marca", "kwietnia", "maja",
                  "czerwca", "lipca", "sierpnia", "września",
                  "października", "listopada", "grudnia");
     @dni_tyg = ("niedziela", "poniedziałek", "wtorek", "środa",
                 "czwartek", "piątek", "sobota");

     print "Content-type: text/html; charset=iso-8859-2\n\n";
     print "<html>\n<head><title>Zegar</title></head>\n";
     print "<body>\n<h1>Aktualny czas</h1>\n";

     ($sek,$min,$godz,$dzien,$mies,$rok,$dztyg) = localtime;

     print "Jest $dni_tyg[$dztyg], $dzien $miesiace[$mies] ";
     print 1900+$rok,", godzina $godz:$min:$sek.\n";
     print "</body>\n</html>\n";
Na początku skryptu tworzymy dwie tablice o nazwach miesiace i dni_tyg, zawierające odpowiednio polskie nazwy miesięcy (w dopełniaczu, jako że tej formy gramatycznej używa się w zapisie daty) oraz dni tygodnia. Po wypisaniu nagłówka HTTP (zauważmy w nagłówku fragment "charset=iso-8859-2", informujący o zastosowanym kodowaniu polskich liter) oraz początku kodu strony korzystamy z wbudowanej funkcji Perla localtime, aby pobrać aktualną wartość zegara systemowego. Ponieważ funkcja ta zwraca listę liczb, zawierającą kolejno sekundy, minuty, godziny itd., po lewej stronie instrukcji podstawienia używamy doraźnie stworzonej takiej listy, składającej się z siedmiu zmiennych.

Uzyskane wartości wykorzystujemy następnie w instrukcji print. W Perlu można umieszczać wartości zmiennych wewnątrz stałych tekstowych ujętych w cudzysłowy, co ułatwia zapis instrukcji w porównaniu z innymi językami programowania (takimi jak C), w których zmienne zawsze musimy oddzielać od stałych np. przecinkami. Korzystając z wcześniej zdefiniowanych tablic dni_tyg i miesiace zamieniamy liczbowe wartości miesiąca i dnia tygodnia zwrócone przez funkcję localtime na ich zapis słowny. Do wartości roku musimy natomiast dodać 1900, ponieważ funkcja localtime traktuje rok 1900 jako "zerowy" i podaje liczbę lat względem niego - czyli np. rok 2000 reprezentowany jest w postaci liczby 100. Wyrażeń nie można jednak umieszczać wewnątrz stałych tekstowych, stąd też zapis 1900+$rokmusimy oddzielić od pozostałej części tekstu, aby Perl wyliczył jego wartość (gdybyśmy umieścili go wewnątrz cudzysłowów, skrypt zamiast "2000" wypisałby nam "1900+100"). Zwróćmy przy okazji uwagę, że ponieważ w pierwszej instrukcji print nie ma sekwencji znaków "\n", tekst wypisywany przez obydwie instrukcje znajduje się w jednym wierszu. Otrzymany wynik przedstawiony jest na rys.4.

W ten sposób uzyskaliśmy skrypt, podający aktualny czas systemowy serwera; łatwo możemy sprawdzić - naciskając kilkakrotnie przycisk "Reload" w przeglądarce - że przy każdorazowym załadowaniu strony podawany będzie inny czas. Zwróćmy uwagę na różnicę między tym rozwiązaniem, a stosowanym często na stronach WWW podawaniem aktualnego czasu z wykorzystaniem Javascriptu; to drugie rozwiązanie podaje nam aktualny czas klienta, czyli komputera, z którego oglądamy stronę, a nie serwera - różnica może być dość istotna, jeżeli np. serwer znajduje się w innej strefie czasowej.

Zamiast ręcznie naciskać przycisk "Reload", możemy spowodować, aby zawartość strony samoczynnie odświeżała się co pewien czas - np. co 10 sekund. Wykorzystamy w tym celu pole Refresh nagłówka HTTP (por. tabela 1). Choć nie znajduje się ono w oficjalnym standardzie protokołu HTTP, rozpoznawane jest przez większość przeglądarek. Zamieńmy zatem pierwszą instrukcję print w powyższym skrypcie na

     print "Content-type: text/html; charset=iso-8859-2\n";
     print "Refresh: 10; url=http://www.serwer.com/katalog/data.cgi\n\n";
Adres podany po znaku równości w drugim wierszu powinien być adresem, do którego przeglądarka ma przejść po upływie 10 sekund - w naszym przypadku jest to ponownie ten sam adres, pod którym znajduje się nasz skrypt. (Równoważnym sposobem - w istocie rozpoznawanym nawet przez większą liczbę przeglądarek - byłoby umieszczenie odpowiedniego znacznika META w kodzie HTML wypisywanej strony; odpowiedni przykład znajduje się na wspomnianej wcześniej stronie WWW ze skryptami).

Zamiast jawnie wpisywać do skryptu jego adres - co niesie ze sobą takie niebezpieczeństwo, że zmieniając nazwę skryptu lub jego lokalizację zapomnimy go odpowiednio zmodyfikować - możemy adres ten skonstruować w skrypcie automatycznie, korzystając ze zmiennych środowiskowych (por. tabela 2). Wszystkie zmienne środowiskowe są dostępne w Perlu jako elementy tablicy asocjacyjnej o nazwie ENV (Perl rozróżnia duże i małe litery w nazwach zmiennych) i można odwołać się do nich poprzez zapis postaci $ENV{'NAZWA'}, gdzie NAZWA jest nazwą zmiennej środowiskowej (tu również rozróżniane są duże i małe litery).

Jak wynika z tabeli 2, adres serwera dostępny jest w zmiennej SERVER_NAME, zaś ścieżka dostępu do skryptu - w zmiennej SCRIPT_NAME. Złożenie wartości tych dwu zmiennych razem i dopisanie na początku "http://" da nam zatem szukany adres. Druga z przedstawionych powyżej instrukcji przybierze wobec tego postać

     print "Refresh: 10; url=http://$ENV{'SERVER_NAME'}$ENV{'SCRIPT_NAME'}\n\n";
Tak zmodyfikowany skrypt, niezależnie od tego, jaką nadamy mu nazwę i pod jakim adresem umieścimy, zawsze będzie poprawnie podawał w polu Refresh swoją własną lokalizację.


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