Einführung
Counter arbeiten normalerweise mit aus Ziffern erzeugten Bildern oder als Bilder zurückgegebenen Strings. Das geht unter PHP
zwar
auch aber nur mit der
gd-Bibliothek (die Bilder erzeugen kann). Diese Bibliothek ist allerdings nicht in unserem
Testsystem vorgesehen und überhaupt (sie ist TIERISCH schwer zu installieren, zumindest unter Linux) eher selten installiert.
Ausserdem ist diese Lösung irgendwie witzlos und so möchte ich einen anderen Lösungsweg vorschlagen:
Wir binden als externe JavaScript-Datei eine PHP-Datei ein. Diese liefert einen Javascript-Quelltext -- und zwar die funktion
getVisitors die als Integer die Anzahl der Besucher zurückliefert. Mit
<script language="JavaScript">
document.writeln(getVisitors());
</script>
kann man diese dann in der HTML-Datei ausgeben - oder auch nicht, falls nicht gewünscht.
Vorteil: Extrem wenig Daten (Text statt Grafik) werden übermittelt, die Daten bleiben dynamisch
(JavaScript-Funtkionen
könnten die Ziffern auch mit Bildern anzeigen oder bei dem 1000sten Besucher Alarm schlagen),
es funktioniert unter allen Browsern, man muss die Visitors nicht darstellen falls ein stiller
Counter gewünscht ist und die Sache braucht erheblich weniger Rechenaufwand als eine
Grafiklösung (für Serverbetreiber interessant).
Nachteil
bei ausgeschaltetem JavaScript funktioniert gar nichts und Netscape ist
pingelig: sollte der Counter ausfallen sieht man unter netscape auch die dahinterliegende Seite
nicht.
Features
Unser Counter soll neben den Anzahlen der Besuchen für den Administrator auch
festhalten, zu welchem Zeitpunkt von welcher IP ein Zugriff erfolgte (um später Statistiken
erzeugen zu können, teilweise müsste man dazu eben doch die GD-Bibliothek benutzen) und von
welcher URL der Benutzer kam (wichtig um z.b. den Erfolg von eintragungen in Suchmaschinen zu
sehen). Hierzu bieten sich (Filter, Gruppierfunktionen, Skalierbarkeit) wieder einmal
Datenbanken an.
Erste Schritte
Als HTML-Datei brauchen wir wie gesagt eine Datei, die eine externe Datei mit <script src=""> einbindet.
<html>
<script language="JavaScript" src="counter.php">
</script>
<body>
Sie sind der <b><script>document.write(getVisitors());</script></b>te Besucher
</body>
</html>
und als PHP-Datei (im Besipiel angesprochen: counter.php)
schreiben wir zuesrt einmal eine PHP-Datei die nur eine mit-eins-belegter Variable ausgibt.
function getVisitors()
{
<?php $i=1; ?>
return <?php echo "$i"; ?>;
}
Beachten Sie dabei, dass die Variable im ersten
Block <?php... ?> im zweiten unverändert vorhanden sind.
So gesehen sind die Blöcke also global. Ausserdem ist es hier verlockend
function getVisitors()
{
$i=1;
<?php echo $i; ?>
}
zu schreiben, was aber nicht funktioniert, weil dann $i bestenfalls eine Javascript-Variable ist und PHP sie nicht einsehen,
geschweige denn mit echo ausgeben kann.
Zugriff in die Datenbank schreiben
Um den Zugriff in eine Datenbank zu schreiben, muss dort zuerst die entsprechende Tabelle vorliegen. Diese erzeugen wir mit
einer Datei namens Setup.php.
Die Datenbank soll enthalten:
Ein Feld für die IP (text)
Ein Feld für die Zugriffszeit (integer)
und ein Feld für die vorherige Seite (text).
Das Datumsfeld machen wir Integer um ein Unix-Timestamp einfügen zu können - mit den Dingern lässt sich i.d.R. viel leichter
Rechnen als mit Formatierten Datumsangaben.
Das machen wir mit einer Datei setup.php die ähnlich des ersten Teiles der Beispieldatei
im
Einrichten eines eigenen Testsystems aufgebaut ist - und die gleiche Funktion hat.
<html>
Starte Setup für Counter....
<?php
$dbh = odbc_connect('testdb', 'aname', 'apwd', SQL_CUR_USE_ODBC);
echo "Connected to db $dbh<br>";
$query = "drop table counter";
$res = odbc_exec($dbh, $query);
$query = "create table counter (zeitpunkt int, ip char(15), refferer char(255))";
$res = odbc_exec($dbh, $query);
odbc_close_all();
?>
... beendet
</html>
Die Tabelle wird gedroppt bevor sie angelegt wird um Änderungen
(z.b. Einfügen eines neuen Feldes) später wirklich wirksam zu machen und
nicht an einer Fehlermeldung a lá die Tabelle existiert schon scheitern
zu lassen.
Diese Datei sollte man allerdings nach Gebrauch in ein anderes Verzeichnis
das nicht von außen angegriffen werden kann verschieben, weil ansonsten jemand
auf die Idee kommen könnte pfadname/setup.php aufzurufen und die gesamten counterdaten
(drop table) löscht. Ein Umbenennen in ein Format das nicht automatisch ausgeführt
wird (z.b. in setup.html) wäre noch um einiges schlimmer, da im odbc-connect, das
dann im Quelltext im Klartext stünde, alle Daten (Benutzername und Passwort) der
Datenbank enthält und Datenbanken i.d.R. auch von außen über eine Internetverbindung
abgefragt werden können - Vollzugriff mit lesen, schreiben, ändern und löschen für den
Angreifer wären die Folge.
Zurück zum eigentlichen: Die Datei counter.php müsste jetzt noch folgendermaßen geändert werden:
function getVisitors()
{
<?php
$dbh = odbc_connect('testdb', 'aname', 'apwd', SQL_CUR_USE_ODBC);
$now = time();
$ip = getenv("REMOTE_ADDR");
$ref = getenv("HTTP_REFERER");
$query = "insert into counter values ($now, '$ip', '$ref')";
$res = odbc_exec($dbh, $query);
$query = "select * from counter";
$res = odbc_exec($dbh, $query);
$numrows = odbc_num_rows($res);
odbc_close_all();
?>
return <?php echo "$numrows"; ?>;
}
time() gibt den schon angesprochenen Unix-Timestamp zurück (auch unter Windows ;)),
REMOTE_ADDR und HTTP_REFERER sind Umgebungsvariablen die IP des Users anzeigen bzw. wo er
herkommt und odbc_num_rows gibt die Anzahl der Datensätze zurück.
Zu schade, dass HTTP_REFERER immer den Namen der HTML-Datei zurückgibt, da diese die scheinbar
letzte ist, die vor der PHP-Datei "angezeigt" wird. Ein weiterer Schwachpunkt meiner
Counter-Einbindung, aber ich denke, die Vorteile überwiegen dennoch.
Todo's
Als to-do braucht der Programmierer noch unbedingt
-
Eine Auswertung für den Administrator. Bisher beschränkt sich das
Programm darauf die Zugriffe festzuhalten. Die Anzahl der Page-Impressions
bekommt man wie gewohnt mit odbc_num__rows.
$dbh = odbc_connect('testdb', 'aname', 'apwd', SQL_CUR_USE_ODBC);
$query = "select * from counter";
$res = odbc_exec($dbh, $query);
echo "number of visitors:".odbc_num_rows($res)." ";
odbc_close_all();
interessant wären Balkengrafiken mit den einzelnen Tagen
und den Visitors. Siehe dazu das XIIIte Kapitel im
Manual.
-
Momentan werden nur sogenannte Page-Impressions gezählt, die Anzahl der tatsächlichen
Besucher kann auch durch die IP-Adresse nur unzureichend geklärt werden (bei
konventionellen Providern bekommen man i.d.R. bei jeder Anwahl eine andere
IP zugeteilt). Das Zählen der Besucher wird erst durch
Cookies
möglich. Zeigen Sie in Ihrer Auswertung doch auch die Anzahl der Besucher!