ABC skryptów CGI

Wstecz Dalej

A teraz obrazek

O wiele popularniejsze od tekstowych są liczniki graficzne. Wynika to m.in. z faktu, że są znacznie prostsze w użyciu dla autora strony - nie trzeba korzystać z SSI, wystarczy dobrze znany znacznik HTML-a <IMG>. Z drugiej strony trzeba zdawać sobie sprawę z tego, że licznik graficzny w istocie liczy liczbę załadowań obrazka, a nie strony, na której ten obrazek jest zawarty; nie będzie reagował na odczytywanie strony przeglądarką tekstową ani też przeglądarką graficzną, w której wyłączono ładowanie obrazków (co robi wiele osób z uwagi na długi czas ściągania grafiki).

Przy tym podejściu skrypt obsługujący licznik nie musi się wcale znajdować na tym samym serwerze, co strona, stąd też w Sieci jest wiele serwerów oferujących takie liczniki jako gotową usługę, możliwą do wykorzystania nawet przez użytkowników nie mogących uruchamiać własnych skryptów CGI. Warto jednak pamiętać, że osoba odwiedzająca naszą stronę może nie móc połaczyć się z serwerem, na którym działa licznik (co nie należy do rzadkości, gdyż serwery "licznikowe" często bywają mocno obciążone). Wówczas nie dość, że licznik nie zarejestruje odwiedzin, to jeszcze w miejscu, gdzie powinien się znajdować, pojawi się ikona "brak obrazka" psująca wygląd strony. Dlatego najlepiej, o ile tylko to możliwe, mieć własny licznik (warto dowiedzieć się, czy na serwerze, na którym znajdują się nasze strony, nie ma gotowego skryptu licznika udostępnionego przez administratora).

Licznik graficzny jest niestety znacznie trudniejszy do zaprogramowania niż tekstowy, gdyż zamiast prostego wypisywania tekstu niezbędne jest generowanie przez skrypt na bieżąco plików graficznych, najczęściej w formacie GIF. W poniższym przykładzie posłużymy się pewnym wybiegiem: wykorzystamy gotowy program do tworzenia takich plików o nazwie fly, dostępny w Internecie pod adresem http://martin.gleeson.com/fly/ (program daje się uruchomić praktycznie w każdym systemie - pod podanym adresem znajdują się wersje dla kilkunastu różnych systemów operacyjnych). Przy okazji pokażemy przykład uruchamiania ze skryptu w Perlu zewnętrznych programów i przekazywania do nich danych.

     #!/usr/bin/perl
     use Fcntl ':flock';
     open (FILE,"+<licznik2.dat");
     flock (FILE,LOCK_EX);
     $hits = <FILE>;
     $hits = $hits+1;
     seek (FILE,0,0);
     print FILE $hits;
     flock (FILE,LOCK_UN);
     close (FILE);

     $|=1;
     print "Content-type: image/gif\n\n";
     open (FLY,"| fly -q");
     print FLY "new\n";
     print FLY "size ",10*length($hits)+8,",20\n";
     print FLY "fill 1,1,255,255,255\n";
     print FLY "string 0,0,0,5,2,giant,$hits\n";
     close (FLY);
Jak łatwo zauważyć, pierwsza część skryptu jest - za wyjątkiem zmienionej nazwy pliku danych - identyczna jak w poprzednim skrypcie; realizuje ona powiększenie o 1 liczby odwiedzin strony przechowywanej w pliku licznik2.dat. Cała różnica między skryptami leży w części drugiej, realizującej wypisywanie wyliczonej wartości.

Na początku wypisywany jest nagłówek HTTP (znaczenie instrukcji $|=1 omówimy dalej), który tym razem specyfikuje typ danych image/gif, jako że wynikiem działania skryptu ma być rysunek w tym formacie. Znak "|" w znajdującej się w następnym wierszu instrukcji open oznacza, że instrukcja ta nie otwiera pliku, lecz tworzy tzw. potok - czyli uruchamia zewnętrzny program przy użyciu komendy następującej po znaku "|" (w tym przypadku "fly -q"; program fly powinien znajdować się w tym samym katalogu, co skrypt) i podłącza się do jego standardowego wejścia.

Potokiem tym do programu fly przesyłane są komendy powodujące kolejno: rozpoczęcie generowania nowego obrazka, ustalenie jego wielkości (wartości zostały dobrane eksperymentalnie; perlowa funkcja length podaje długość tekstu będącego jej argumentem, czyli w tym przypadku liczbę cyfr wyniku, który należy wypisać), wypełnienie tła kolorem białym (jeżeli chcielibyśmy uzyskać inny kolor, należy zamienić trójkę liczb 255,255,255 na wartości RGB interesującego nas koloru) oraz wypisanie - czcionką o wielkości "giant" - wartości zmiennej $hits, przechowującej liczbę załadowań strony (tu również, jeżeli chcemy zmienić czarny kolor tekstu, należy zamienić 0,0,0 na odpowiednią wartość RGB). Zamknięcie strumienia instrukcją close powoduje wygenerowanie przez program fly obrazka i wysłanie go na standardowe wyjście, które - podobnie jak standardowe wyjście skryptu - przyłączone jest do serwera WWW.

Tu pojawia się problem synchronizacji wyników wypisywanych przez sam skrypt i zewnętrzny program. Gdy dane ze standardowego wyjścia jakiegokolwiek programu przesyłane są do innego programu (bądź pliku), są one zazwyczaj buforowane: oznacza to, że dane są zbierane w pamięci operacyjnej i wysyłane dopiero, gdy uzbiera się ich dostateczna ilość (np. 512 bajtów), bądź w chwili zakończenia pracy programu. Zachowanie takie spowoduje jednak, że dane z programu fly najprawdopodobniej trafią do serwera WWW wcześniej, niż nagłówek wypisany przez skrypt. Zaburzony zostanie zatem prawidłowy format danych wymaganych na wyjściu skryptu (por. rozdział "Między serwerem a skryptem") i otrzymamy komunikat "Internal server error".

Radą na ten problem jest umieszczona przed poleceniem wypisującym nagłówek instrukcja o postaci $|=1. $| to jedna ze specjalnych zmiennych systemowych Perla, która steruje buforowaniem standardowego wyjścia skryptu. Nadanie tej zmiennej wartości 1 powoduje wyłaczenie buforowania, a więc nagłówek zostanie przesłany do serwera WWW niezwłocznie po wykonaniu instrukcji print, przed uruchomieniem programu fly. Zapewni to prawidłową kolejnośc wyników na wyjściu. (Nadając zmiennej $| wartość 0 można ponownie włączyć buforowanie).

Skrypt taki wywołujemy na stronie WWW w ogólnie znany sposób:

     Ta strona była odwiedzana <img src="licznik_g.cgi" alt="[licznik]"> razy.
czego wynik możemy zobaczyć na rys.8. Licznik ten jest oczywiście bardzo prosty wizualnie, gdyż jest tylko ilustracją zasady tworzenia takich skryptów. Zainteresowani mogą ściągnąć z Internetu (kilka przydatnych adresów wymienionych jest na końcu tego opracowania) szereg bardziej złożonych liczników, składających obraz ze wzorców cyfr zapisanych w odrębnych plikach GIF.

Analogicznie, jak w poprzednim przykładzie, w wywołaniu skryptu licznik_g.cgi możemy używać parametrów, jeżeli jeden skrypt ma obsługiwać liczniki na wielu stronach, np.

     Ta strona była odwiedzana <img src="licznik_g.cgi?glowna" alt="[licznik]"> razy.


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