Licznik odwiedzin odporny na odświeżanie

JarekX

Wstęp

W tym artykule chciałbym poruszyć sprawę licznika odwiedzin który zlicza 1 osobę tylko raz, niezależnie od tego ile razy strona zostanie odświeżona. Skrypt będzie się opierać na ciastkach. Przy wejściu na stronę będzie sprawdzał czy klient dostarczył ciasteczko. Jeśli tak, licznik nie zapisuje Twojej wizyty. Jeśli nie, skrypt wysyła ciasteczko, oraz zapisuje wizytę.

Sposób wykonania

Dla niewiedzących, do zapisywania cookie służy funkcja setCookie().

setCookie('name', 'value', czas przechowywania na komputerze)

Oczywiście funkcja przyjmuje też inne argumenty, ale nie będą nam potrzebne. Wszystkie parametry oprócz nazwy są opcjonalne. Czas przechowywania jest datą wyrażoną w UNIX timestamp, czyli formie zapisu daty, oznaczającej luczbę sekund od 1 stycznia 1970 roku (w strefie czasowej +0, UTC).

Teraz zabieramy się za licznik. Tworzymy dwa pliki: licznik.php i counter.n. Plik counter.n. zostawiamy pusty.

Wpisujemy teraz na początku pliku licznik.php:

<?
setCookie("visited", "1", time() + 3600*3); 
//Wysyła cookie do przeglądarki użytkownika

I koniecznie w następnych znacznikach kodu wpisujemy:

<?
if (file_exists("counter.n")) {
   // Sprawdza czy plik istnieje
   $file = fopen("counter.n", "r"); // otwiera plik
   flock($file, 1); // blokuje plik, tak by inny proces nie mógł nim operować
   $ile = fgets($file, 100); 
   //Odczytuje wartość z pliku counter.n

   flock($file, 3); // odblokowywuje plik
   fclose($file); //zamyka plik
   if ($_COOKIE["visited"] != "1") { //Sprawdza, czy użytkownik był na stronie 
     $ile++; //Zwiększa wartość o jeden tylko po pierwszym wejściu
   }
} else {
  $ile = 1; // jeśli plik nie istnieje, wyświetli się 1
}

$file=fopen("counter.n", "w"); // otwiera plik do zapisu
flock($file, 2); // blokuje do zapisu
fwrite($file, $ile); //zapisuje wartość
flock($file, 3); // odblokowuje plik
fclose($file); //zamyka plik

echo $ile; //Wyświetla wartość

5 komentarzy

Fajny skrypt. Prosty, funkcjonalny i do ogarnięcia przez początkujących.
Po drobnych modyfikacjach wykorzystałem go na swojej stronie: http://www.fourup.pl
Dziękuję.

Można zapisać to prościej (krócej) i zarazem wydajniej; dodatkowo kod odporny na niepoprawną zawartość pliku licznika:

$file = 'counter.n';
$ile = @file_get_contents($file) and is_numeric($ile) and $x = true or $ile = 1;
!$_COOKIE['visited'] and fwrite(fopen($file, 'w'), $x ? ++$ile : $ile);
setcookie('visited', true, time()+3600*3);
echo $ile;

W sumie dałoby się ładniej napisać, ale późno jest i mi się nie chce ;P

Już poprawione :)

na oko moze to byc wina braku rozijania zmiennych powinno byc $_COOKIE["visited"] zamiast $visited.

Przeprowadziłem mały test (1000 odwiedzin) i muszę z przykrością stwierdzić, że nie działa :D Oczywiście cookie mam włączone!