ABC skryptów CGI

Wstecz Dalej

Daj się policzyć!

W skryptach CGI często niezbędne jest zapamiętanie lub zmodyfikowanie danych w pliku znajdującym się na dysku serwera. Klasycznym przykładem takiego zastosowania mogą być popularne liczniki odwiedzin strony. Skrypt obsługujący taki licznik musi przechowywać liczbę załadowań strony w jakimś pliku na serwerze i aktualizować ją przy każdym kolejnym załadowaniu.

Spotykane są dwa zasadnicze typy liczników: tekstowe, realizowane z wykorzystaniem SSI, oraz graficzne, które umieszcza się na stronie przy użyciu znacznika <IMG>, tak jak zwykły obrazek. Zacznijmy od licznika tekstowego. Przykład takiego licznika przedstawiony został w artykule "CGI - sposób na dynamiczne strony WWW", który ukazał się w MI 6/2000. Przedstawimy tu nieco udoskonaloną wersję tego skryptu, wzbogaconą o tzw. blokowanie pliku zawierającego liczbę pobrań strony, co zabezpiecza przed próbą modyfikacji zawartości tego pliku równocześnie przez dwie kopie skryptu i w efekcie wpisania do niego błędnej wartości (co mogłoby się zdarzyć, gdyby nasza strona była bardzo popularna i oglądało ją wielu użytkowników naraz):

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

     print "Content-type: text/plain\n\n";
     print $hits;
Znajdujący się na początku skryptu wiersz use Fcntl ':flock' sygnalizuje, że będziemy chcieli skorzystać z modułu bibliotecznego zawierającego funkcje blokowania plików (przedstawiona postać polecenia jest właściwa dla wersji Perla 5.x, najczęściej obecnie używanej - w starszych wersjach wymagana będzie nieco inna składnia). Wiersz ten jest bardzo istotny - w razie jego pominięcia zawarte w skrypcie instrukcje flock nie działają prawidłowo, choć skrypt nie sygnalizuje żadnych błędów (!). Następnie instrukcja open otwiera plik licznik.dat - znaki "+<" umieszczone przed nazwą pliku oznaczają, że plik ten otwieramy zarówno do odczytu, jak i do zapisu (">" oznaczałoby otwarcie pliku do zapisu - ze skasowaniem ewentualnej poprzedniej zawartości, ">>" - do dopisywania tekstu na końcu pliku, zaś znak "<" lub brak jakiegokolwiek znaku - otwarcie tylko do odczytu). Plik ten musi znajdować się w tym samym katalogu na serwerze, co skrypt. Jest to zwykły plik tekstowy, zawierający jedynie aktualną liczbę pobrań strony - na początku, gdy umieszczamy go na serwerze, wpisujemy w nim po prostu liczbę 0 (jako, że strona nie była jeszcze odczytywana ani razu). Po otwarciu pliku następuje jego zablokowanie instrukcją flock - parametr LOCK_EX oznacza, że od tego momentu żaden inny program nie będzie mógł używać tego pliku - musi czekać na jego zwolnienie instrukcją flock z parametrem LOCK_UN.

W kolejnych dwu wierszach skryptu następuje odczytanie wartości z pliku i zwiększenie jej o 1. Następnie instrukcja seek "przewija" plik z powrotem na początek, przygotowując go do zapisu nowej wartości. Wartość ta zostaje zapisana do pliku instrukcją print i plik zostaje odblokowany, a następnie zamknięty.

Tak przygotowany skrypt wykorzystujemy w treści strony przy użyciu mechanizmu SSI, umieszczając na stronie np. następujący fragment:

     Ta strona była czytana <!--#exec cgi="licznik.cgi" --> razy.
(oczywiście nie zapomnijmy o nadaniu stronie rozszerzenia .shtml lub innego odpowiedniego dla naszego serwera). Wynik wykonania skryptu możemy obejrzeć na rys.7.

Musimy rzecz jasna pamiętać o odpowiednich prawach dostępu do pliku licznik.dat. Plik ten jest przez skrypt nie tylko odczytywany, ale i zapisywany. Musimy zatem tak ustalić prawa dostępu do niego, aby serwer WWW miał możliwość jego modyfikacji - w przeciwnym wypadku skrypt nie będzie działał. Więcej informacji na ten temat znajduje się w notce "Prawa dostępu do plików".

Jeżeli mamy kilka stron, na których chcemy zainstalować liczniki, nie musimy dla każdej strony tworzyć osobnego skryptu różniącego się jedynie nazwą wykorzystywanego pliku danych. Nazwę pliku - bądź tylko pewien jej fragment - można przekazać do skryptu jako parametr. Umieśćmy np. na stronie głównej następujący fragment:

     Ta strona była czytana <!--#include virtual="licznik.cgi?glowna" --> razy.
a na podstronie, której odwiedziny chcemy odrębnie zliczać, fragment:

     Jesteś <!--#include virtual="licznik.cgi?podstrona" --> gościem na tej stronie.
Użycie polecenia #include virtual= zamiast #exec cgi= jest w tym przypadku niezbędne z uwagi na konieczność przekazania parametru do skryptu. W samym skrypcie zaś zmieńmy instrukcję open otwierającą plik na poniższą:

     open (FILE,"+<$ENV{'QUERY_STRING'}.dat");
Spowoduje to, iż skrypt będzie używał pliku o nazwie podanej jako parametr z dołączonym rozszerzeniem .dat - a więc dla pierwszej ze wspomnianych powyżej stron pliku glowna.dat, dla drugiej zaś podstrona.dat. Metodę tę bez kłopotu można rozszerzyć na dowolną liczbę stron.


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