================================================
Eine Anmerkung vorweg:
Ich habe sämtliche Quelltextbereiche nur deshalb in "quotes" gepackt,
weil die Darstellung in den "code"-Bereichen fehlerhaft ist
und sehr schlecht lesbar wäre.
================================================
Vom Hitcounter zum Besucherzähler
Hitcounter mit einfacher IP-Adress-Sperre ("IP-Sperre"/"Reload-Sperre")
Wer mit sich mit PHP beschäftigt, stolpert früher oder später über so genannte Hitcounter:
Fast jede private Website hat einen. Irgendwo auf der Homepage befindet sich ein Text in der Art:
"Hallo, sie sind Besucher Nummer 08154711 auf dieser Website."
Ein simpler Hitcounter ist schnell gebastelt:
(1) Eine Textdatei (Hitcounter-Datei) mit einem Anfangswert anlegen.
(2) Den Anfangswert aus der Datei einlesen.
(3) Den Wert um Eins erhöhen und wieder in die Datei schreiben.
Blöderweise reagiert so ein Zähler jedesmal, wenn jemand die Seite aufruft.
Wer zwanzigmal die Seite lädt, erzeugt auch 20 Hits, und der Counter zählt munter mit, obwohl doch derselbe Besucher nur einmal gezählt werden sollte.
Um aus so einem Hitcounter einen echten Besucherzähler zu machen ist etwas mehr Aufwand nötig:
Der Zähler muss sich die IP-Adressen von gezählten Besuchern für einen gewissen Zeitraum merken.
Normalerweise genügt dafür ein Tag. Wer also 24 Stunden später wieder auf die Website kommt, darf wieder als neuer Besucher gezählt werden -- wir wollen schließlich nicht pingelig sein.
Das folgende Skript tut genau dies. Weiterhin speichert es alles, was es zum Zählen von Besuchern braucht,
in einer einzigen Datei. Diese hat folgenden prinzipiellen Aufbau:
1111568968,127.0.0.3 Unix-Datestamp, IP-Adresse
1111568968,127.0.0.3 dito
1111568968,127.0.0.3 dito
... dito
47110815 Der aktuelle (letzte) Zählerstand
Es werden nur die IP-Adressen der Besucher während der letzten 24 Stunden erfasst. Ältere Einträge werden bei einem neuen "Hit" automatisch entfernt.
Um das Skript universell verwendungsfähig zu machen, habe ich es in eine Unterfunktin gepackt.
Sie heißt "count_hits()" und erwartet einen optionalen Parameter: den Pfad zur Hitcounter-Datei (in der die IP-Adressen und der Zählerstand gespeichert werden).
Phne Parameter aufgerufen, versucht die Funktion die Hitcounter-Datei im aktuellen Verzeichnis unter dem Namen "counter_data.txt" zu speichern.
Ging alles glatt, enthält der Rückgabewert der Funktion den aktuellen Zählerstand.
Im Fehlerfall wird die Zahl Null zurückgegeben.
Ein Tag hat 24 x 60 x 60 Sekunden. Wer beim Testen nicht so lange warten will, setzt einen Inline-Kommentar "//" vor die nächste Zeile.
Dann erlaubt der Counter schon nach ca. 10 Sekunden eine Erhöhung des Zählerstandes.
Nun erfolgen einige "Einstellarbeiten". Wer das Format der Hitcounter-Datei nicht mag, kann hier beispielsweise das Komma gegen ein Semikolon austauschen.
Die Variable $webroot bekommt den Basispfad der aktuellen Website. Im Gegensatz zu $_SERVER['DOCUMENT_ROOT'] enthält sie auch schon erweiterte Pfade.
Beispiel: Bei Lima-City-Webspace ist $webroot = $_SERVER['DOCUMENT_ROOT'].'/username/html'.
Jetzt müssen wir uns ein paar Gedanken über die Ausgabe von Fehlermeldungen machen.
Fehlermeldungen sollten nicht im Browserfenster auftauchen, es sei denn es ist wirklich etwas ganz Schlimmes passiert.
Ansonsten ist es besser, unser Skript schreibt Meldungen in eine separate Datei -- ein so genanntes Logfile.
Der folgende Code sorgt dafür, dass die Fehlermeldung ins Standard-Error-Logfile des Webservers oder in die in $elog_file angegebene Datei geschrieben wird.
Die IP-Adresse des Besuchers holen wir uns aus den Server-Umgebungsvariablen.
Dabei sollten wir auch die Besucher nicht vergessen, die über einen Proxy ins Internet gehen.
Wo kommen die Hits hin? (Und her?) Den Pfad zur Hitcounter-Datei basteln wir uns jetzt zusammen:
Fängt der (unserer Funktion übergebene) Pfad mit einem "/" (Slash) an, nehmen wir an, dass damit ein Unterverzeichnis von $webroot gemeint ist.
Ansonsten wird einfach vom aktuellen Pfad ausgegangen.
Rufen wir das Skript das erste Mal auf, ist die Hitcounter-Datei noch nicht vorhanden.
Der folgende Codeabschnitt erzeugt in diesem Fall eine leere Datei.
Die Hitcounter-Datei wird zum gleichzeitigen Lesen und Schreiben geöffnet.
Wir wollen alle Manipulationen an der Datei in einem Aufwasch durchführen.
Sonst könnte in der Zwischenzeit ein anderes Skript dazwischenfunken und unsere Datei unbrauchbar machen.
Die Hitcounter-Datei wird Zeile für Zeile eingelesen.
Jede Zeile wird mit explode() in die Bestandteile Timestamp und IP-Adresse zerlegt.
Diese Bestandteile werden in ein assoziatives Array gepackt.
Den Schlüssel (Key) stellt dabei der Timestamp und den Wert (Value) die IP-Adresse dar.
Die Anweisung if($past_time > $xpl[0]) continue; sorgt dafür, dass Einträge, die älter als 24 Stunden sind, übersprungen werden.
Hat die Zeile nur einen Eintrag (also kein Komma vorhanden), so handelt es sich um die Anzahl der Hits. Der Einlesevorgang kann dann beendet werden.
Eventuell auftretende Fehler sollten wir besser abfangen.
Schließlich könnte die Hitcounter-Datei ja auch fehlerhafte Einträge enthalten.
Die im Array $list vorhandenen Einträge müssen nun einer nach dem anderen auf Übereinstimmung mit der IP-Adresse des aktuellen Besuchers geprüft werden.
Gleichzeitig übernehmen wir die Timestamp-IP-Kombinationen in unseren Ausgabe-Puffer-String $buffer.
Der Hitcounter soll selbstverständlich nur dann um Eins erhöht werden, wenn der Zugriff auf die Seite "berechtigt" erfolgte.
In diesem Fall müssen wir auch einen neuen Eintrag in die Hitcounter-Datei hinzufügen, damit der selbe Besucher für die nächsten 24 Stunden gesperrt wird.
Die gesamte neue Liste von IP-Adressen und Timestamps wird nun vom Ausgabe-Puffer-String ins Logfile geschrieben.
Die neue Dateilänge ist möglicherweise geringer als die alte. Daher muss die Datei noch auf die neue Länge gekürzt werden -- wenn nötig.
Danach können wir die Datei wieder freigeben.
Der neue Counter-Wert wird an das aufrufende Hauptprogramm übermittelt.
Beispiel eines Aufrufes im Hauptprogramm
Andere Anwendung
Da das Skript als Unterfunktion auch mit verschiedenen Dateinamen aufgerufen werden kann, sind auch Anwendungen denkbar, die auf dem ersten Blick nichts mit Besucherzählern zu tun haben.
So ist eine einfache Ja-/Nein-Abstimmung mit zwei verschiedenen Dateien durchaus realisierbar.
Erweiterte Anwendung
Besser formatierte (und eventuell fehlerbereinigte) Quelltexte für count_hits.php und das Aufruf-Beispiel befinden sich auf der Seite:
http://alopex.pyrokar.lima-city.de/index.php/PHP/Hitcounter.html
Dort kann der Counter auch in Aktion erlebt werden.
Fanden Sie diesen Text nützlich?
Ja: http://alopex.pyrokar.lima-city.de/xlink.php/tut_ja
Nö: http://alopex.pyrokar.lima-city.de/xlink.php/tut_nein