PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Counter nur mit PHP?!?



ml0206
29-03-2003, 17:32
Hallo,
ich hab' versucht einen Counter nur mit PHP zu machen. Ich bin so weit, dass ich eine Datei habe, in der die IP des Benutzers und die Zugriffszeit (in sec seit '70) gespeichert wird. Das Script vergleicht dann die neue IP mit den der letzten 5 Minuten und aktualisiert bei Erfolg den Timestamp. So vermeide ich den Count beim Reload. Das funktioniert theoretisch auch ganz nett, nur ist er vor kurzem wieder auf 0 gesprungen.
Ich vermute, dass es daran lag, dass jemand den Counter aktiviert hat und ein zweiter praktisch im gleichen Moment; das Prob. dabei ist, dass ich die Datei in eine Variable einlese und sie leere, dann füge ich der Variable die Informationen hinzu und schreibe die Datei wieder. Kommt ein zweiter Client im richtigen Moment trifft er auf eine leere Datei und schreibt nur eine IP rein; logisch :(

Wie kann ich das umgehen, bzw. kenn jemand How-Tos oder so, wo ich mich etwas schlauer machen könnte?

Danke schonmal und viele Grüße

Mathias

Gaert
29-03-2003, 17:52
Hallo!

Das erinnert mich irgendwie ein wenig an meine Betriebssystemevorlesung (Kritischer abschnitt - Mutex - Semaphore - Monitore - etc...), aber das tut nix zur Sache :D .

Folgende Tipps:
1. Schreibe die Zahl des Counters in eine Datei, und die IP's in eine andere.
2. Such mal bei Google, Counterskripte gibts genug!
3. Gugg dir mal mein Beispiel an (ist unter deinem Aspekt nicht getestet, dürfte aber funktionieren)

Beispiel (hab ich vor längerer Zeit kurz zusammengeschrieben):


<?php
/*
#####################################
# Besucherzaehler von Nico Gaertner
#####################################
*/
// Optionen:
$anzdir = "anzahl.txt" ;
$ipdir = "ip.txt" ;

$fontfile = "arial.ttf";
if(!$size)
$fontsize = 16;
else
$fontsize = $size;

$fontangle = 0;

$color1['r'] = 51;
$color1['g'] = 102;
$color1['b'] = 153;

$color2['r'] = 255;
$color2['g'] = 255;
$color2['b'] = 255;

/*###################################*/
//Programmcode

$userip=$_SERVER['REMOTE_ADDR'];
$ip_array=file($ipdir);
$new_array=Array();
$yes=false;
foreach($ip_array as $line=>$ip) {
if (trim($userip)==trim($ip)) $yes=true;
if ($line < 20) $new_array[]=$ip;
}

$anzahl = fopen("$anzdir", "r+");
$nummer = fgets( $anzahl, 20 );
$nummer = intval( $nummer );

if (!$yes) {
$ips=implode("\n",$new_array);
if ($ips)
$ips=$userip."\n".$ips;
else
$ips=$userip;

$ipfile = fopen("$ipdir", "w+");
fputs($ipfile, $ips);

$nummer++;
fseek($anzahl, 0);
fputs( $anzahl, $nummer );
fclose($ipfile);
}

/*###################################*/
//Erzeugen der grafischen Ausgabe als JPEG

header("Content-type: image/jpeg");

$text = $text . ' ' . $nummer;
$dimtxt = ImageTTFBBox( $fontsize, $fontangle, $fontfile, $text );

$border = 2;
$txtsizex = abs($dimtxt[4] - $dimtxt[0]);
$txtsizey = abs($dimtxt[5] - $dimtxt[1]);
$imgsizex = $txtsizex + 3*$border;
$imgsizey = $txtsizey + 5*$border;
$txtposx = $border;
$txtposy = $txtsizey + $border;

$img = imageCreate( $imgsizex, $imgsizey);
$col1 = imagecolorallocate( $img, $color1['r'], $color1['g'], $color1['b']);
$col2 = imagecolorallocate( $img, $color2['r'], $color2['g'], $color2['b']);

imagefill( $img, 0, 0, $col1);
imageTTFText( $img, $fontsize, $fontangle, $txtposx, $txtposy, $col2,
$fontfile, $text );

imageJPEG( $img );
imagedestroy( $img );
?>

The Ripper
30-03-2003, 15:11
Das wäre eigentlich ein typisches Einsatzgebiet für die Funktion flock() (http://www.php.net/manual/en/function.flock.php), mit der man sicherstellen kann, dass immer nur ein Prozess auf die Datei zugreifen kann.
Direkt nach dem Öffnen der Datei rufst du flock() mit LOCK_EX auf, die Funktion wartet dann bis in die Datei geschrieben werden kann.
Nach dem Schreiben rufst du die Funktion mit LOCK_UN auf, dass wieder andere Prozesse in die Datei schreiben können.

Die Warnung unter der Funktionsbeschreibung gefällt mir aber nicht, vielleicht funktioniert dieser Weg nicht so wie gewünscht.