Eigenbaucounter
Achim
- php
Hallo!
Ich bin dabei, mich in PHP einzuarbeiten und hab mal einen kleinen Zähler gebastelt...
Dabei habe ich mich an einem Counterscript orientiert, das ich gefunden habe. Allerdings habe ich die Reloadsperre rausgemacht. Der Zählerstand wird in eine Datei counter.txt geschrieben, die anfangs nur das Zeichen 0 (null) enthält. Bei jedem Zugriff wird die Datei geöffnet, der Wert um 1 erhöht und dann wieder geschrieben. Anschließend wird das ganze grafisch ausgegeben.
Bei einem Testlauf mit mehreren Leuten war der Zählerstand auf einmal von über 500 auf einen zweistelligen Wert zurückgefallen. Kann das damit zusammenhängen, dass zwei Anfragen exakt gleichzeitig kamen? Und wenn ja, wie könnte man das verhindern?
Hier mal das Script:
<?php
header("Content-type: image/gif");
$back = imagecreatefromgif("counter.gif");
$posx = 70; /* zum Festlegen des Mittelpunktes des Counterstandes */
$posy = 26; /* zum Festlegen des Mittelpunktes des Counterstandes */
$angle = 0; /* Winkel des Counterstandes */
$fontsize = 16; /* Schriftgröße */
$color = -0; /* Schriftfarbe */
$font = "aribl0.ttf"; /* Schriftart */
$zd = fopen("counter.txt", "r");
$zs = fread($zd, filesize("counter.txt"));
fclose($zd);
$zs++;
$zd = fopen("counter.txt", "w");
fwrite($zd, $zs);
fclose($zd);
$box = imagettfbbox($fontsize, $angle, $font, $zs);
$posx2 = $posx - floor((abs($box[0]) + abs($box[2]) + abs($box[4]) + abs($box[6])) / 4);
$posy2 = $posy + floor((abs($box[1]) + abs($box[3]) + abs($box[5]) + abs($box[7])) / 4);
imagettftext($back, $fontsize, $angle, $posx2, $posy2, $color, $font, $zs);
imagegif($back);
imagedestroy($back);
?>
Danke für Eure Hilfe.
Achim
Hallo
Bei einem Testlauf mit mehreren Leuten war der Zählerstand auf einmal von über 500 auf einen zweistelligen Wert zurückgefallen. Kann das damit zusammenhängen, dass zwei Anfragen exakt gleichzeitig kamen? Und wenn ja, wie könnte man das verhindern?
Hier mal das Script:
<?php
...
$zd = fopen("counter.txt", "r");
$zs = fread($zd, filesize("counter.txt"));
fclose($zd);
...
?>
Da sollte flock() mit rein.
http://www.selfphp.info/funktionsreferenz/dateisystem_funktionen/flock.php
Tschö, Auge
Hallo!
Da sollte flock() mit rein.
http://www.selfphp.info/funktionsreferenz/dateisystem_funktionen/flock.php
Hab ich genauso gemacht wie beschrieben. Und wieder mehrere Leute drauflosgelassen. Bei ca. 1300 war die Datei counter.txt plötzlich leer... Und hat natürlich nicht mehr gezählt. Wie kann das denn kommen?
Achim
Hallo
Hab ich genauso gemacht wie beschrieben. Und wieder mehrere Leute drauflosgelassen. Bei ca. 1300 war die Datei counter.txt plötzlich leer... Und hat natürlich nicht mehr gezählt. Wie kann das denn kommen?
Genau weiß ich es auch nicht.
Dein Code:
$zd = fopen("counter.txt", "r");
$zs = fread($zd, filesize("counter.txt"));
fclose($zd);
$zs++;
$zd = fopen("counter.txt", "w");
fwrite($zd, $zs);
fclose($zd);
<spekulier>
Du benutzt für den Dateizeiger zum Lesen und zum Schreiben
den gleichen Variablennamen ($zd). Benenne einen der Zeiger
um, ich vermute, daß bei gleichzeitigen Zugriffen $zs verloren geht.
</spekulier>
Tschö, Auge
Hallo!
Habe hier was gefunden: http://www.dynamic-webpages.de/50.tutorials.php?dwp_tutorialID=5
Da heißt es im Begleittext zu einem Counter in der Form, wie ich ihn hatte:
Dieser Counter ist nicht für stark frequentierte Sites (>2000 Aufrufe/Tag) oder Sites, die zu einer bestimmten Zeit von sehr vielen aufgerufen wird geeignet, da viele gleichzeitige Aufrufe sehr rechenintensiv sind.
Und im Test kamen wir auf mehrere 100 Aufrufe pro Minute. Vielleicht war's schlicht zuviel...
Achim
Hallo
Dieser Counter ist nicht für stark frequentierte Sites (>2000 Aufrufe/Tag)
Denkst Du mehr als 2.000 Aufrufe pro Tag zu haben?
oder Sites, die zu einer bestimmten Zeit von sehr vielen aufgerufen wird geeignet, da viele gleichzeitige Aufrufe sehr rechenintensiv sind.
Schon allein deshalb würde ich die Dateizeiger für das
Lesen und Schreiben unterschiedlich benennen, obwohl
auch in diesem Skriptbeispiel beide Dinge mit einem
Variablennamen erledigt werden. In diesem Fall mit:
$datafile
$datafile = @fopen($filename , "r");
if ($datafile <=0)
{
echo "Datenfile nicht gefunden oder kaputt!";
exit;
}
Was der Quatsch soll weiß wohl auch nur der Autor.
$datafile = @fopen($filename , "r") or die("Datenfile nicht gefunden oder kaputt!");
ist da wohl besser.
Und im Test kamen wir auf mehrere 100 Aufrufe pro Minute. Vielleicht war's schlicht zuviel...
Das wären pro Tag (rein statistisch) 144.000 Aufrufe,
das sind _höchstwahrscheinlich_ein_paar_mehr_ als
2.000 Aufrufe täglich.
;-)
Tschö, Auge
Hallo!
Denkst Du mehr als 2.000 Aufrufe pro Tag zu haben?
Nein, natürlich nicht. War ja nur zum Testen... :-)
Aber hab wieder was gelernt. Danke!
Achim
Hallo Achim,
wie hast Du es denn gemacht mit dem Locking?
Dateihandle holen (rw)
dreimal wiederholen bis Erfolg
abfragen, ob Exclusiv-Locking möglich
Wert auslesen
Wert incrementieren
Wert zurückschreiben
Locking aufheben
sonst Fehlermeldung
Datei schließen
Die Datei Unix-Systemen allerdings nicht wirklich gelockt, sondern nur mit einem Tag versehen. Wie das ganze auf Windows- oder Novellsystemen läuft, weiß ich (noch) nicht. Die kennen überlicherweie kein "Advisory Locking". Da müsste das Apache entweder selbst implementiert haben, oder auf Mandatory Locking ausweichen.
Liebe Grüße aus http://www.braunschweig.de
Tom