besucherzähler mit statistik

06.06.2007

in diesem tutorial werde ich dir eirklären wie man einen besucherzähler mit statistikanzeige für die eigene homepage baut.
dabei gehe ich am anfang auf die einstellungen in der datenbank ein, danach zeige ich wie die besuchszeiten gespeichert werden und schliesslich werde ich noch auf die verschiedenen anzeigemöglichkeiten eingehen.

damit du den counter auch auf deinem webspace zum laufen bekommst, sollte er mysql version 4.1.1 oder hoher installiert haben, ausserdem noch php und den phpyadmin zum managen der mysql datenbank. ausserdem sollten dir die zugangsdaten für die datenbank bekannt sein.

noch zwei hinweise vorneweg:
nummer eins: dieses tutorial setzt schon ein paar grundkenntnisse in sachen php und mysql vorraus. falls du also mit einigen begriffen die hier vorkommen probleme hast, schlage ich dir vor dir vorher ein php grundwissen anzueignen. geeignete einführungen sind bei webstatt unter "PHP Tutorials und Anleitungen" zu finden.
nummer zwei: wenn du fragen, anregungen oder verbesserungs- vorschläge zu diesem tutorial hast, dann lass es mich das wissen: am besten, du benutzt einfach die kommentarfunktion am ende der seite.

eins: vorbereitung der datenbank

weil die zugriffszeiten in der datenbank gespeichert werden sollen, wird sie als als erstes für den besucheransturm vorbereitet: dazu werden zwei neue tabellen angelegt. die eine speichert die zugriffszeit auf die datenbank, die andere die ip-adresse des benutzers (dazu später mehr).

die tabellenstruktur wird mithilfe des mysql-admin eingetragen. falls du es noch nicht getan hast, wäre jetzt ein guter zeitpunkt ihn jetzt zu öffnen. wenn du die datenbank ausgewählt hast in der die neuen tabellen erstellt werden sollen, dann öffne bitte das mysql-eingabefeld, dass sich hinter diesem button verbirgt öffnen des sql-eingabefeldes im phpmyadmin. dann kannst du den folgenden code kopieren und in das sql-eingabefeld einfügen.
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE `counter` (
`id` int(10) NOT NULL auto_increment,
`datum` datetime NOT NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM ;


CREATE TABLE `counter_ip` (
`id` int(10) NOT NULL auto_increment,
`ip` varchar(255) NOT NULL,
`datum` datetime NOT NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM ;


wenn du OK gedrückt hast und keine fehlermeldung erscheint ist die datenbank für die nutzerdaten vorbereitet.

zwei: die zugriffszeiten ermitteln und speichern

hast du deinen texeditor bereits geöffnet? gut, dann jann es ja losgehen. zuerst wird eine verbindung zur mysql-datenbank aufgebaut. die variablen $db_host, $db_name, $db_nutzer und $db_passwort stehen dabei für die zugangsdaten zur datenbank und sind idealerweise in einer konfigurationsdatei ("konfigu- ration.php") gespeichert. so sparst du dir später scheib- und kopierabeit.
1
2
3
4
5
<?
// verbindung zur datenbank herstellen
$verbindung = mysql_connect($db_host, $db_nutzer, $db_passwort) OR die("fehler_keine_verbindung");
mysql_select_db($db_name) or die("fehler_keine_datenbank");
?>


damit steht die verbindung zur datenbank, ab jetzt kann auf alle tabellen zugegriffen und geschrieben werden. um das gleich mal zu testen, wird in die tabelle "counter" das aktuelle datum mit uhrzeit im DATETIME-format eingetragen. dabei mache ich mir die date()-funktion von php und die datums- und zeitfunktionen von mysql zunutze.
1
2
3
4
<?php
$eintrag_counter 
"INSERT INTO `counter` (`datum`) VALUES ('".date("Y-m-d H:i:s")."')";
$eintragen_counter mysql_query($eintrag_counter);
?>


jetzt wird bei jedem seitenaufruf die aktuelle zeit in die datenbank eingetragen. um zu sehen ob alles richtig funktioniert sollten die ergebnisse am besten mal angezeigt werden. mit dem folgenden codeschnipsel werden alle einträge in der tabelle "counter" zusammengezählt und hochgeladen.
1
2
3
4
5
<?php
// alle zugriffszeiten zusammenzählen
list($zaehlerstand) = mysql_fetch_row(mysql_query("SELECT COUNT(*) FROM `counter` ORDER BY `id`"));
echo 
$zaehlerstand;
?>


zusammengefasst in einer php-datei sieht das ganze dann so aus:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
// die konfigurationsdatei einbinden
include("../konfiguration.php");

// verbindung zur datenbank herstellen
$verbindung mysql_connect($db_host$db_nutzer$db_passwort) OR die("fehler_keine_verbindung");
mysql_select_db($db_name) or die("fehler_keine_datenbank");

// datum des besuches in die datenbank einfügen
$eintrag_counter "INSERT INTO `counter` (`datum`) VALUES ('".date("Y-m-d H:i:s")."')";
$eintragen_counter mysql_query($eintrag_counter);

// alle zugriffszeiten zusammenzählen
list($zaehlerstand) = mysql_fetch_row(mysql_query("SELECT COUNT(*) FROM `counter` ORDER BY `id`"));
echo 
$zaehlerstand;
?>


in der 2. zeile wird die konfigurationsdatei eingebunden, in der die zugangsdaten für die datenbank gespeichert sind.

hast du den code oben als datei gespeihert, lade diese am besten mal auf deinen server und rufe sie dann im webbrowser auf. hast du alles richtig gemacht, dann sieht die datei so aus wie dieser testcounter, den ich schonmal vorbereitet habe. (dass sich die besucherzahlen unterscheiden sollte klar sein).

dieser zähler ist ja bis jetzt ganz nett, leider hat er noch einen kleinen schöheitsfehler: bei jedem neuladen der datei erhöht sich der zählerstand um 1. damit zeigt der zähler gar eigentlich gar nicht die anzahl der besucher die hier waren an, sondern wie oft die seite geladen wurde. wer also die seite ganz oft neu lädt, kann den zählerstand massiv nach oben treiben und so die statistik verfälschen.

es ist also wichtig, dass der besucherzähler bei jedem besucher nur um 1 steigt, egal wie oft er die seite neu lädt. dabei hilft seine ip-adresse. diese wird bei der einwahl ins internet vergeben und ist einmalig. somit lassen sich verschiedene internetnutzer anhand ihrer ip-adresse unterscheiden.

netterweise kann php die ip-adresse des benutzers auslesen und in die datenbank speichern. für den besucherzähler bedeutet das: bevor die besuchszeit in der datenbank gespeichert wird, soll das php-script die ip-adresse des besuchers auslesen und mit den ip-adressen abgleichen, die in der tabelle "counter_ip" eingetragen sind. ist die ip-adresse des besuchers noch nicht in der datenbank, dann wird sie in die tabelle "counter_ip" und die besuchszeit in die tabelle "counter" eingetragen. hat der besucher dagegen die seite schon einmal besucht (und ist seine ip bereits in der datenbank gespeichert) wird nichts eingetragen. am ende soll natürlich wieder die anzahl der besucher angezeigt werden.

so. das war jetzt eine menge text, am besten zeige ich jetzt mal wie das ganze in php aussieht.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
// ip-adresse des Besuchers holen
$ip $REMOTE_ADDR;

// die abfrage an die datenbank: welche datensaetze sollen ausgelesen werden?
$abfrage_counter_ip "SELECT * FROM `counter_ip`";
$ergebnis_counter_ip mysql_query($abfrage_counter_ip);

// in der schleife werden alle ips in der satenbank durchgegangen.
// ist die ip des benutzers dabei, wird die variable auf TRUE umgestellt,
// was bewirkt dass nichts in die datenbank eingetragen wird
$ip_in_datenbank FALSE;
while(
$row mysql_fetch_object($ergebnis_counter_ip)){
    if(
$row->ip == $ip){
        
$ip_in_datenbank TRUE;
    }
}

if (
$ip_in_datenbank == FALSE){
// ip und datum in die ip-tabelle eintragen
    
$eintrag_counter_ip "INSERT INTO `counter_ip` (`ip`, `datum`) VALUES ('".$ip."', '".date("Y-m-d H:i:s")."')";
    
$eintragen_counter_ip mysql_query($eintrag_counter_ip);

// datum und zugriffszeit in der countertabelle speichern
    
$eintrag_counter "INSERT INTO `counter` (`datum`) VALUES ('".date("Y-m-d H:i:s")."')";
    
$eintragen_counter mysql_query($eintrag_counter);
}
?>


fügt man den seitenanfang und die ausgabe dazu, sieht der code so aus:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
// die konfigurationsdatei einbinden
include("../konfiguration.php");

// verbindung zur datenbank herstellen
$verbindung mysql_connect($db_host$db_nutzer$db_passwort) OR die("fehler_keine_verbindung");
mysql_select_db($db_name) or die("fehler_keine_datenbank");

// ip-adresse des Besuchers holen
$ip $REMOTE_ADDR;

// die abfrage an die datenbank: welche datensaetze sollen ausgelesen werden?
$abfrage_counter_ip "SELECT * FROM `counter_ip`";
$ergebnis_counter_ip mysql_query($abfrage_counter_ip);

// in der schleife werden alle ips in der satenbank durchgegangen.
// ist die ip des benutzers dabei, wird die variable auf TRUE umgestellt,
// was bewirkt dass nichts in die datenbank eingetragen wird
$ip_in_datenbank FALSE;
while(
$row mysql_fetch_object($ergebnis_counter_ip)){
    if(
$row->ip == $ip){
        
$ip_in_datenbank TRUE;
    }
}

if (
$ip_in_datenbank == FALSE){
// ip und datum in die ip-tabelle eintragen
    
$eintrag_counter_ip "INSERT INTO `counter_ip` (`ip`, `datum`) VALUES ('".$ip."', '".date("Y-m-d H:i:s")."')";
    
$eintragen_counter_ip mysql_query($eintrag_counter_ip);

// datum und zugriffszeit in der countertabelle speichern
    
$eintrag_counter "INSERT INTO `counter` (`datum`) VALUES ('".date("Y-m-d H:i:s")."')";
    
$eintragen_counter mysql_query($eintrag_counter);
}

// alle zugriffszeiten zusammenzählen
list($zaehlerstand) = mysql_fetch_row(mysql_query("SELECT COUNT(*) FROM `counter` ORDER BY `id`"));
echo 
$zaehlerstand;
?>


auch zu dieser datei habe ich ein onlinebeispiel hochgeladen.

jetzt wird also bei jeder neuen ip ein eintrag in die datenbank vorgenommen. doch was ist, wenn der besucher zu einem späteren zeitpunkt (z.b. einen tag) erneut auf die seite kommt? sollte er dann nicht doch wieder in der statistik auftauchen, weil er die seite ja neu aufgerufen hat? dazu müsste seine ip-adresse aber nach einer betimmten zeit wieder aus der datenbank gelöscht werden. schlauerweise wird beim speichern der ip auch gleich der dazugehörige zeitpunkt in der tabelle "counter_ip" gesichert. mit folgendem code werden eninträge die älter als eine bestimmte zeit (z.b. 1 stunde) sind automatisch gelöscht.
1
2
3
4
5
6
7
8
9
10
11
12
13

<?php
// zeit, nach der die ip-adresse aus der
// datenbank gelöscht werden soll, in minuten.
// bitte 2-stellig angeben
$loeschzeit_minuten "60";

// zu alte einträge werden aus der datenbank gelöscht
$abfrage_loeschen "DELETE FROM `counter_ip` WHERE `datum` < NOW() - INTERVAL ".$loeschzeit_minuten." MINUTE";
mysql_query($abfrage_loeschen);
echo 
mysql_error();
?>


die ganze datei, die ich auch als livebeispiel zur verfügung gestellt habe sieht dann wie folgt aus. im livebeispiel habe ich die löschzeit auf eine minute gestellt, erst das neuladen der seite nach 1 minute erzeugt also einen höheren zählerstand.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
// die konfigurationsdatei einbinden
include("../konfiguration.php");

// Zeit, nach der die Ip-Adresse aus der
// Datenbank gelöscht werden soll, in Minuten
// 2 - stellig angeben
$loeschzeit_minuten "01";

// ip-adresse des Besuchers holen
$ip $REMOTE_ADDR;

// verbindung zur datenbank herstellen
$verbindung mysql_connect($db_host$db_nutzer$db_passwort) OR die("fehler_keine_verbindung");
mysql_select_db($db_name) or die("fehler_keine_datenbank");

// die abfrage an die datenbank: welche datensaetze sollen ausgelesen werden?
$abfrage_counter_ip "SELECT * FROM `counter_ip`";
$ergebnis_counter_ip mysql_query($abfrage_counter_ip);

// alte werte löschen
$abfrage_loeschen "DELETE FROM `counter_ip` WHERE `datum` < NOW() - INTERVAL ".$loeschzeit_minuten." MINUTE";
mysql_query($abfrage_loeschen);
echo 
mysql_error();

// in der schleife werden alle ips in der satenbank durchgegangen.
// ist die ip des benutzers dabei, wird die variable auf TRUE umgestellt,
// was bewirkt dass nichts in die datenbank eingetragen wird
$ip_in_datenbank FALSE;
while(
$row mysql_fetch_object($ergebnis_counter_ip)){
    if(
$row->ip == $ip){
        
$ip_in_datenbank TRUE;
    }
}

if (
$ip_in_datenbank == FALSE){
// ip und datum in die ip-tabelle eintragen
    
$eintrag_counter_ip "INSERT INTO `counter_ip` (`ip`, `datum`) VALUES ('".$ip."', '".date("Y-m-d H:i:s")."')";
    
$eintragen_counter_ip mysql_query($eintrag_counter_ip);

// datum und zugriffszeit in der countertabelle speichern
    
$eintrag_counter "INSERT INTO `counter` (`datum`) VALUES ('".date("Y-m-d H:i:s")."')";
    
$eintragen_counter mysql_query($eintrag_counter);
}

// alle zugriffszeiten zusammenzählen
list($zaehlerstand) = mysql_fetch_row(mysql_query("SELECT COUNT(*) FROM `counter` ORDER BY `id`"));
echo 
$zaehlerstand;
?>


damit ist auch teil zwei fertig, der dritte folgt jetzt.

kommentar schreiben



mensch oder maschine? den code bitte in das eingabefeld eintragen. danke.


smilies
permalink
zurück zur übersicht