Hallo,
<?
$fn = "counter.txt";if (file_exists($fn))
{
$fp = fopen($fn, "r");
$zahl= fgets($fp,10);
fclose($fp);
}
else
{
$zahl = 0;
}$zahl = $zahl + 1;
echo "<b>$zahl Besucher seit dem 01.07.03";$fp = fopen($fn, "w");
flock($fp,2);
fputs($fp,$zahl);
flock($fp,3);
fclose($fp);
?>
Den Code habe ich ein wenig abgewandelt getestet.
Der Code:
<?php
$fn = "counter.txt";
if (file_exists($fn))
{
$fp = fopen($fn, "r");
$zahl= fgets($fp,10);
fclose($fp);
}
else
{
$zahl = 0;
}
$zahl = $zahl + 1;
echo "<b>$zahl Besucher seit dem 01.07.03";
$zahl.="\n".serialize($_SERVER).
serialize($_SERVER).
serialize($_SERVER).
serialize($_SERVER).
serialize($_SERVER).
serialize($_SERVER).
serialize($_SERVER);
$fp = fopen($fn, "w");
flock($fp,2);
fputs($fp,$zahl);
flock($fp,3);
fclose($fp);
?>
Im Endeffekt wird $zahl in meinem Test auf eine Größe von 8979 Byte gebracht, um den eigentlichen Schreibprozess zu verlangsamen.
Das erschreckende Ergebnis nach einem Test mit dem servereigenen Tool "ab" ($ ./ab -n 50000 -c 10 http://test/semaphoren/test.php) in der Ausgabe am Browser danach:
<b>2898 Besucher seit dem 01.07.03
Selber Test wiederholt ergibt folgendes:
<b>10610 Besucher seit dem 01.07.03
Selbst bei einem erneutem Test ($ ./ab -n 50000 -c 2 http://test/semaphoren/test.php), wo der Server nicht durch MaxRequestsPerChild gezwungen war, neue Threads zu erstellen, ergab sich folgendes:
<b>1072 Besucher seit dem 01.07.03
Das Testsystem ist Linux mit Apache 2.0.53 und PHP 5.0.4 als Handler des Servers.
[1] Es gibt da eine Aussage von Eddi (to grip), dass das Mandatory Locking auf manchen Systemen überhaupt nicht funktioniert. Wenn wir die nötige Zeit finden, untersuchen wir das näher. Eddi hat schon einige Lösungen erarbeitet.
Die Lösung über Semaphoren scheint zu kranken, da noch die konkurierenden Zugriffe eingerechtet werden. Soweit das derzeit abklärbar war, ist ein Denkfehler dahingehend aufgetreten, daß wie bei Dir erst nach einem erfolgten Zugriff eine "Sperre" gesetzt wird. Der Code ist unter http://eddi.to-grip.de/PHP/semaphor/?0.0.1.php einsehbar und verständlich kommentiert.
Eine parallel erdachte, aber noch nicht in Code umgewandeltes, Idee, auf eben einem multi-threaded Server eine sichere Aufstellung von Zugriffen zu erstellen, die für Deine Zwecke -wie geschaffen- wäre, ist, wenn PHP als Handler läuft, dem Server entweder über apache_setenv() eine Variable, ähnlich wie mod_setenvif, oder eben gleich mit mod_setenvif zu setzen, mit der wie in http://httpd.apache.org/docs-2.0/mod/mod_log_config.html#customlog beschreiben eine gesonderte Logdatei geführt wird. Diese würde pro Request um ein byte erweitert. Die Zugriffe ließen sich mit filesize() ermittel. Ein täglicher Cornjob würde die Datei wieder auf 0 byte setzen und dessen Größe in einer anderen Datei mit Datum vermerken, sadaß nicht nach einem Monat die Datei im GB-Bereich wäre.
Das setzt aufgrund der notwendigen Konfigurationsdirektiven Schreibrecht auf die primäre Serverkonfigurationsdatei voraus.
Generell lohnt es sich mal beim Support eines Hosters anzurufen, wo für einen Kundenaccount die Logdateien abgelegt werden, weil man letztlich nur die Logdateien mittels PHP zu parsen braucht, um selben Effekt zu erziehlen, aber mit dem Unterschied, daß man die Arbeit des Aufzeichnens der Zugriffe nicht dopelt machen muß!
Gruß aus Berlin!
eddi