Licznik w PHP
Tym razem opiszę jeden z najprostszych skryptów PHP, a zarazem najpowszechniej używanych. Mianowicie prosty licznik, ale jednak odporny na odświeżanie.
Odporność na odświeżanie można zrealizować na trzy sposoby: sprawdzając nagłówek HTTP_REFERER, przy pomocy ciasteczek oraz korzystając z sesji. Użycie dwóch sposobów (tzn. ciasteczek i nagłówka) charakteryzuje się wystarczającą odpornością.
O ciasteczkach krótko
Czym są ciasteczka (ang. cookies)? Ciasteczka są plikami tekstowymi, przechowywanymi przez przeglądarki i zawierającymi informacje, z których korzystają serwisy internetowe. Mało kto je zauważa, ale w każdej przeglądarce jest ich pełno. Zazwyczaj również słyszy się, że są niebezpieczne. Jest to bzdurą, ponieważ w ciasteczku nie da się zapisać niczego co mogłoby być niebezpieczne. Jednak jeśli ktoś, używając przeglądarki internetowej, sprawdzał na przykład pocztę i zapomniał się wylogować, to (jeśli przeglądarka nie została zrestartowana) istnieje możliwość podejrzenia cudzej poczty przez osoby, które korzystają z tego samego komputera i z tej samej przeglądarki. Ich niebezpieczeństwo wynika z bezmyślności użytkowników.
Nieco kodu
Skrypt licznika, który jest odporny na przeładowania, to w rzeczywistości dwa bloki kodu liczące po kilka linijek każdy. Pierwszym blokiem jest blok ustawiający ciasteczko, sprawdzający zmienną HTTP_REFERER i ewentualnie dopisujący ilość odwiedzin do pliku. Drugi blok wyświetla tylko liczbę, która jest ilością odwiedzin.
Przed rozpoczęciem działania należy stworzyć plik, w którym będą odnotowywane odwiedziny. Niech ten plik nazywa się licznik.txt. Jego zawartość początkowa to:
0;
Aby wszystko działało poprawnie, prawa dostępu do tego pliku powinny być 666 (rw-rw-rw-), czyli powinien być możliwy odczyt i zapis dla wszystkich.
Pierwszy blok:
<?php
if((!isset($_COOKIE['licznikowe-ciacho'])) && (!strstr($_SERVER['HTTP_REFERER'], "strona.pl"))) {
$plik = fopen("licznik.txt", "r");
$tekst = fread($plik, filesize("licznik.txt"));
$dane = explode(";", $tekst);
fclose($plik);
$plik = fopen("licznik.txt", "w");
flock($plik, 2);
$dane[0]++;
fwrite($plik, "$dane[0];", 15);
flock($plik, 3);
fclose($plik);
setcookie("licznikowe-ciacho", "zliczono", 0);
}
else {
$plik = fopen("licznik.txt", "r");
$tekst = fread($plik, filesize("licznik.txt"));
$dane = explode(";", $tekst);
}
?>
Jak widać, ten blok składa się tylko z kilku instrukcji, które zostaną wykonane zależnie od warunku. Warunek spełni się jeśli przeglądarka nie wysłała skryptowi ciasteczka (ciasteczko nie ustawione) oraz jeśli w zmiennej $_SERVER['HTTP_REFERER'] nie znajduje się adres naszej strony. Adresem strony w przykładzie jest strona.pl, ale oczywiście należy to zamienić na odpowiedni adres. Ważne jest, żeby nie używać w tym miejscu przedrostka www.. W ostatniej linijce bloku spełnionego warunku znajduje się instrukcja tworzenia ciasteczka. Pierwszym parametrem funkcji setcookie() jest nazwa ciasteczka, drugim zawartość tego ciasteczka, a trzecim okres jego ważności. W tym przykładzie jest to zero, co oznacza, że ciasteczko zostanie usunięte w momencie wyłączenia przeglądarki, ale równie dobrze można ustawić mu ważność na dwa dni (zamiast zera należy wpisać time()+172800), czy na dwa tygodnie (time()+1209600).
Niespełnienie warunku spowoduje jedynie odczytanie ilości odwiedzin, bez ich inkrementacji.
Pierwszy blok powinien być umieszczony w dokumencie, w miejscu, w którym nie zostały jeszcze wysłane wszystkie nagłówki, czyli w miejscu, w którym do przeglądarki nie zostały wysłane znaki CR-LF CR-LF (dwa znaki nowej linii). W praktyce, takim miejscem jest zawsze początek dokumentu, a właściwie skryptu PHP. Taki wymóg spowodowany jest tym, że ciasteczko trafia do przeglądarki właśnie jako nagłówek.
Drugi blok:
<p>Jesteś <?php echo($dane[0]); ?> gościem na mojej stronie.</p>
Powyższy zapis jest oczywiście przykładowy. Treść może zostać zmieniona, ale najważniejszą częścią, która musi pozostać jest: <php echo($dane[0]); ?>.
