template

Index :: PHP/MySQL :: Counter (Text-basiert)

Statistiken sind nicht nur für den Seitenbetreiber sondern auch für Besucher interessant. Zwar ist die Anzeige der Seitenaufrufe, ehemals ein obligatorischer Bestandteil vieler Homepages, mittlerweile etwas aus der Mode gekommen, aber die Anzahl der Downloads für bestimmte Dateien (meist Audio, Video, PDF oder ZIP-Archive) dient Besuchern i.d.R. als willkommene Information - rein psychologisch erleichtern solche Angaben die Entscheidung, ebenfalls dieses oder jenes Angebot herunterzuladen.

Die einfachste Art und Weise, einen Zähler zu integrieren, besteht im Auslesen (und Aktualisieren) einer simplen einzeiligen Textdatei welche den aktuellen numerischen Counter-Wert als String enthält. Am Ende der Zeile sollte kein Zeilenumbruch stehen.
Es können auch mehrere Counter-Werte (z.B. mittels Komma getrennt) in der Textdatei untergebracht werden, um im Falle umfangreicherer Statistiken die Anzahl der Dateien (und damit auch der Zugriffe) zu reduzieren.


Besucherzähler

Hierbei benutzen wir eine Counter-Datei namens cnt.txt, die im Root-Verzeichnis liegt und mit der Ziffer '0' verbelegt wurde.
Um den Zählerstand zu ermitteln, liest PHP ihren Inhalt aus und fügt die Zahl per echo() ins HTML-Dokument ein. Bevor die Ausgabe erfolgt, muss allerdings geprüft werden, ob es sich um einen neuen Besucher handelt: in diesem Falle wird der Zähler gleich um 1 hochgezählt (und so wieder zurückgeschrieben).
Da wir nicht jeden Aufruf berücksichtigen, sondern nur neue Besucher zählen wollen, testen wir eine bestimmte Session-Variable (hier: $_SESSION['cnt_flag']); ist sie bereits gesetzt, dann handelt es sich um einen alten Besucher - ist sie noch nicht gesetzt, dann handelt es sich um einen neuen Besucher, wir erhöhen den Counter und setzen die Session-Variable (hier: auf den Dummywert '1').
Solange also die Session eines Besuchers aktiv ist, fließen seine Folgeaufrufe nicht mehr in die Statistik mit ein. Mittels session_set_cookie_params() lässt sich die Lebensdauer einer Session (in Sekunden) festlegen, d.h. nach Ablauf dieser Zeit wird der entsprechende Besucher wieder als neu gewertet. Im nachfolgenden Beispiel (einer Home-Seite, z.B. index.php) wird diese Lebensdauer auf 3600 Sekunden (= 1 Stunde) gesetzt:
Php Einleitung
session_set_cookie_params(3600); //Session (hier: auf 1 Stunde) zeitlich begrenzen session_start(); //und starten bzw. weiterfuehren
Weiter unten, im BODY, den Zählerstand anzeigen:
... Besucher: <?php $fp=fopen('cnt.txt','r+'); //Counter-Datei oeffnen $c=fgets($fp,10); //Counter auslesen if (!isset($_SESSION['cnt_flag'])){ //Falls neuer Besucher $c++; //Counter hochzaehlen rewind($fp); //Zeiger auf Dateianfang fwrite($fp,$c); //Counter zurueckschreiben $_SESSION['cnt_flag']=1; //Flag in Session setzen } fclose($fp); //Datei schliessen echo $c; //Counterstand ins Dokument schreiben ?><br> ...

Downloadzähler (einzeln)

Bei einem Downloadzähler wird im Grunde ein Link überwacht - mit anderen Worten: es werden Clicks gezählt. Der Mechanismus funktioniert folgendermaßen: Anstatt direkt auf die Zieldatei zu verweisen, ruft man ein PHP-Skript auf. Als GET-Parameter übergibt man dabei den Namen oder die ID der gewünschten Datei. Das Skript kann nun den entsprechenden Zähler aktualisieren und führt schließlich eine Umleitung auf die eigentliche Zieldatei durch. Das Umleiten geschieht durch explizites Setzen einer neuen URL (Location) mittels header()-Anweisung, z.B.:
header('Location: http://www.server.com/path/file.mp3');
Was diese Art von redirection betrifft, lässt sich als Location natürlich auch eine remote Adresse angeben - für den Fall dass die Zieldatei auf einem anderen Server gehostet ist.

Wie beim Besucherzähler verwenden wir auch hier eine einfache Counter-Datei (namens 1.txt), die aus organisatorischen Gründen im Ordner cnt untergebracht ist. Dieser Ordner kann dann auch für weitere Counter-Dateien benutzt werden.

Das Aktualisieren des Zählers sowie die Umleitung erfolgen im Beispiel über das Modul item.php (die zu überwachende Datei, hier ein Audiofile namens 1.mp3, liegt dabei übrigens im Ordner mp3):
<?php
if (($nr=intval($_GET['nr']))!=1) exit; //DateiNr holen und pruefen

$fp=fopen('cnt/1.txt','r+'); //Counter-Datei oeffnen
$c=fgets($fp,10);            //Counter auslesen
$c++;                        //Counter hochzaehlen
rewind($fp);                 //Zeiger auf Dateianfang
fwrite($fp,$c);              //Counter zurueckschreiben
fclose($fp);                 //Datei schliessen
//auf Zieldatei umleiten
header('Location: http://www.myserver.net/mp3/1.mp3');
?>
Im HTML-Code der Downloadseite wird nun im Link 'Mozarts kleine Nachtmusik' die item.php mit passendem Parameter angegeben. Unter dem Link sollen die Downloads angezeigt werden - der Inhalt der Counter-Datei wird wie gehabt gelesen und ausgegeben:

Der Download-Link und die Counter-Anzeige im BODY:
... Meine Tip zum besseren Einschlafen:<br> <a href='item.php?nr=1' target='_blank'>Mozarts kleine Nachtmusik</a><br> Bisherige Downloads: <?php //aktuellen Counter holen $fp=fopen('cnt/1.txt','r'); //Counter-Datei oeffnen echo fgets($fp,10); //Counter auslesen und ins Dokument schreiben fclose($fp); //Datei schliessen ?><br> ...
Basierend auf diesem System können leicht auch weitere Counter (2.txt, 3.txt, etc.) implementiert werden.

Ebenso ließe sich item.php etwas flexibler gestalten; beispielsweise mit zusätzlicher Übergabe eines Dateinamens:
<?php
$nr=intval($_GET['nr']);     //CounterNr holen
$fn=intval($_GET['fn']);     //Dateiname holen

$fp=fopen('cnt/.$nr.'.txt','r+'); //Counter-Datei oeffnen
$c=fgets($fp,10);            //Counter auslesen
$c++;                        //Counter hochzaehlen
rewind($fp);                 //Zeiger auf Dateianfang
fwrite($fp,$c);              //Counter zurueckschreiben
fclose($fp);                 //Datei schliessen
//auf Zieldatei umleiten
header('Location: http://www.myserver.net/mp3/'.$fn.'.mp3');
?>
Der Link im HTML-Code könnte jetzt so aussehen (für Nachtmusik.mp3):
<a href='item.php?nr=1&fn=Nachtmusik' target='_blank'>Mozarts kleine Nachtmusik</a><br>

Downloadzähler (gruppiert)

Das gruppierte Zählen funktioniert prinzipiell auf die gleiche Weise wie beim obigen Einzel-Zähler, mit dem Unterschied, dass eine Counter-Datei keinen individuellen Wert, sondern ein ganzes Array von Zähler-Werten enthält.

Im folgenden Beispiel sollen auf einer Seite die Tracks von 3 CDs zum Herunterladen angeboten werden. Analog dazu sind im Ordner cnt drei Counter-Dateien (alb1.txt, alb2.txt und alb3.txt) hinterlegt, die manuell mit Komma-separierten Zählern initialisiert wurden. Die Anzahl dieser Zähler richtet sich nach der Anzahl der jeweiligen Tracks. So sähe z.B. alb1.txt (für Album 1 mit seinen 5 Tracks) so aus:
0,0,0,0,0

Für das Counter-Update und die Umleitung ist auch hier wieder unsere item.php verantwortlich. Sie erwartet im GET-Parameter 'a' die Nummer [1...3] des Albums und im GET-Parameter 't' die Nummer [1...n] des Tracks.
Das Hochzählen besteht aus dem Einlesen des Counter-Arrays, dem Erhöhen das entspechenden Elements und dem Zurückschreiben des Arrays.
Anschließend wird für die Umleitung die Adresse der Zieldatei zusammengebaut. Im Beispiel liegen die Tracks durchnummeriert in separaten Ordern, die nach dem Album benannt sind. Diese Album-Ordner wiederum liegen im Ordner mp3 (etwa mp3/MyFirst/01_MyFirst.mp3).
<?php
if (($anr=intval($_GET['a']))<1||$anr>3) exit; //AlbumNr holen und pruefen
$tnr=intval($_GET['t']);                       //TrackNr holen

$fp=fopen('cnt/alb'.$anr.'.txt','r+');     //Counter-Datei oeffnen
$n=count($c=explode(',',fgets($fp,200)));  //alle Counter auslesen
if ($tnr<1||$tnr>$n){ fclose($fp); exit; } //TrackNr pruefen
++$c[$tnr-1];             //Counter des Tracks hochzaehlen
rewind($fp);              //Zeiger auf Dateianfang
fwrite($fp,join(',',$c)); //Counter-Array zurueckschreiben
fclose($fp);              //Datei schliessen

$alb=array('MyFirst','MySecond','MyThird'); //Albumnamen definieren
$alb=$alb[$anr-1];                          //aktuellen Albumnamen holen
if ($tnr<10) $tnr='0'.$tnr;                 //TrackNr formatieren
//auf Zieldatei umleiten
header('Location: http://www.myserver.net/mp3/'.$alb.'/'.$tnr.'_'.$alb.'.mp3');
?>
Im HTML-Code wird pro Album das jeweilige Counter-Array in $c[] eingelesen und dessen Elemente hinter den Titeln angezeigt. Der als Verweisadresse dienenden item.php übergibt man die entsprechenden Parameter für Album und Track.

Tracks im BODY auflisten:
... Mein 1. Album: MyFirst<br> <?php //Counter-Array f. Album 1 holen $fp=fopen('cnt/alb1.txt','r'); //entsprechende Counter-Datei oeffnen $c=explode(',',fgets($fp,200)); //alle Werte in einem Array merken fclose($fp); //Datei schliessen ?> 01 <a href='item.php?a=1&t=1' target='_blank'>Titel_1</a> (<?php echo $c[0]; ?>)<br> 02 <a href='item.php?a=1&t=2' target='_blank'>Titel_2</a> (<?php echo $c[1]; ?>)<br> 03 <a href='item.php?a=1&t=3' target='_blank'>Titel_3</a> (<?php echo $c[2]; ?>)<br> 04 <a href='item.php?a=1&t=4' target='_blank'>Titel_4</a> (<?php echo $c[3]; ?>)<br> 05 <a href='item.php?a=1&t=5' target='_blank'>Titel_5</a> (<?php echo $c[4]; ?>)<br> ... Mein 2. Album: MySecond<br> <php //Counter-Array f. Album 2 holen $fp=fopen('cnt/alb2.txt','r'); $c=explode(',',fgets($fp,200)); fclose($fp); ?> 01 <a href='item.php?a=2&t=1' target='_blank'>Titel_1</a> (<?php echo $c[0]; ?>)<br> 02 <a href='item.php?a=2&t=2' target='_blank'>Titel_2</a> (<?php echo $c[1]; ?>)<br> 03 <a href='item.php?a=2&t=3' target='_blank'>Titel_3</a> (<?php echo $c[2]; ?>)<br> 04 <a href='item.php?a=2&t=4' target='_blank'>Titel_4</a> (<?php echo $c[3]; ?>)<br> ... ...
Wie schon beim Einzelzähler demonstriert, könnte man auch hier die item.php um einen Parameter für 'Dateiname' (und evtl. auch einen Parameter für 'Albumname') erweitern, etwa:
<?php
$anr=intval($_GET['a']);  //AlbumNr holen
$tnr=intval($_GET['t']);  //TrackNr holen
$an=intval($_GET['an']);  //Albumname holen
$fn=intval($_GET['fn']);  //Trackname holen

$fp=fopen('cnt/alb'.$anr.'.txt','r+');     //Counter-Datei oeffnen
$n=count($c=explode(',',fgets($fp,200)));  //alle Counter auslesen
if ($tnr<1||$tnr>$n){ fclose($fp); exit; } //TrackNr pruefen
++$c[$tnr-1];             //Counter des Tracks hochzaehlen
rewind($fp);              //Zeiger auf Dateianfang
fwrite($fp,join(',',$c)); //Counter-Array zurueckschreiben
fclose($fp);              //Datei schliessen

//auf Zieldatei umleiten
header('Location: http://www.myserver.net/mp3/'.$an.'/'.$tnr.'_'.$fn.'.mp3');
?>
Ein Link im HTML-Code würde dann so aussehen:
03 <a href='item.php?a=1&t=3&an=MyFirst&fn=Blabla' target='_blank'>Blabla</a>

Index :: PHP/MySQL


template