Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PHP-Counter resettet immer wieder

14 views
Skip to first unread message

Jens Fittig

unread,
Feb 25, 2011, 5:33:22 AM2/25/11
to
Hallo, ich nutze folgenden Code für einen Counter:

function increase_save_count() {
if (!file_exists(PFAD."counter_files/count.txt")) {
error("no_counter_file");
} elseif (!is_writable(PFAD."counter_files/count.txt")) {
error("count_unwriteable");
} else {
$counts = file(PFAD."counter_files/count.txt");
$count = trim($counts[0]);
$count++;
$fh = fopen(PFAD."counter_files/count.txt","wb");
flock($fh, LOCK_EX);
fwrite($fh, $count);
fclose($fh);

$string = $count . " " . date("H:i:s",time(TRUE)) . " " .
$_SERVER[ "REMOTE_ADDR" ] . "\n" ;
$logfile = PFAD."counter_files/countlog.txt";
$fh = fopen($logfile,"a");
flock($fh, LOCK_EX);
fwrite($fh, $string);
fclose($fh);

}
return;
}


Dieser Counter springt so alle paar tausend Counts, aber unregelmäßig,
auf "0".

Wie kann das passieren? Wie kann ich das verhindern?

Der Code stammt aus einer fertigen Codeschnipselsammlung. Ich habe nur
den Zusatz bezüglich der Mitspeicherung im "countlog" drangehängt
damit ch den Counter anhand des Logfiles wieder neu setzen kann.

Ein ähnliches Script in einer anderen Webseite per Perl/CGI hat das
selbe Problem. Alle paat zehntausend counts springt es willkürlich auf
"0"


Dr. Franz-Josef Huecker

unread,
Feb 25, 2011, 8:44:20 AM2/25/11
to
At Fri, 25 Feb 2011 11:33:22 +0100, Jens Fittig <inva...@gmx.de>
wrote:

> Hallo, ich nutze folgenden Code für einen Counter:
>
> function increase_save_count() {
> if (!file_exists(PFAD."counter_files/count.txt")) {
> error("no_counter_file");
> } elseif (!is_writable(PFAD."counter_files/count.txt")) {
> error("count_unwriteable");
> } else {
> $counts = file(PFAD."counter_files/count.txt");
> $count = trim($counts[0]);
> $count++;
> $fh = fopen(PFAD."counter_files/count.txt","wb");
> flock($fh, LOCK_EX);
> fwrite($fh, $count);
> fclose($fh);

Hi Jens

Schau dir mal den Counter (siehe Link unten) an (Code und Beispiel).
Mit dem gab es nach meinem Kenntnisstand bisher noch keine Probleme
und vielleicht bekommst du dort eine Idee, wie du deinen Counter
optimieren kannst oder ersetzen.

Der aelteste Counter, den ich verwende - freilich in TCL, steht jetzt
bei 187095 (siehe Link unten) und ist durchaus vergleichbar, weil er
einen vergleichbaren Code verwendet..

Franz-Josef

http://www.huecker.com/msw/php/php_man_f.shtml

http://www.nlp.de/exp_com/

--
Dr. Franz-Josef Huecker
W3: http://www.huecker.com
Email: in...@huecker.com

Jens Fittig

unread,
Feb 25, 2011, 9:15:32 AM2/25/11
to

Dr. Franz-Josef Huecker schrieb:


> > $counts = file(PFAD."counter_files/count.txt");
> > $count = trim($counts[0]);
> > $count++;

> > $fh = fopen(PFAD."counter_files/count.txt","wb");
> > flock($fh, LOCK_EX);
> > fwrite($fh, $count);
> > fclose($fh);

> Hi Jens

Hi Franz-Josef



> Schau dir mal den Counter (siehe Link unten) an (Code und Beispiel).

> aus http://www.huecker.com/msw/php/php_man_f.shtml

| $count = @file ( $file ); // Inhalt von file lesen, - in Array speichern.
| $state = $count[0]; // Status einlesen.
| ++$state; // Zähler um eins erhöhen.

| $fp = fopen ( $file, "w" );
| @fwrite ( $fp, $state ); // counter.dat aktualisieren.
| fclose ( $fp );

Das Beispiel entspricht fast meiner Routine. Nur hat sie kein "flock".
Damit wäre nach meinem bisherigen Verständnis meine Routine sicherer.
Wobei es nicht "meine" Erfindung ist. Ich habe sie aus einer
Codesammlung und nur eingebaut.

> Mit dem gab es nach meinem Kenntnisstand bisher noch keine Probleme
> und vielleicht bekommst du dort eine Idee, wie du deinen Counter
> optimieren kannst oder ersetzen.

> Der aelteste Counter, den ich verwende - freilich in TCL, steht jetzt
> bei 187095 (siehe Link unten) und ist durchaus vergleichbar, weil er
> einen vergleichbaren Code verwendet..

Ich habe die MIO schon lange überschritten. <g> Pro Tag im Schnitt ca.
300 zählende Zugriffe.

Danke für den Tip


Dr. Franz-Josef Huecker

unread,
Feb 25, 2011, 1:15:54 PM2/25/11
to
At Fri, 25 Feb 2011 15:15:32 +0100, Jens Fittig <inva...@gmx.de>
wrote:

> Ich habe die MIO schon lange überschritten. <g> Pro Tag im Schnitt ca.
> 300 zählende Zugriffe.

Hi Jens

Bei dem Traffic ist flock natuerlich zwingend. Mein Hinweis zeigte
auf ein Einfuehrungsbeispiel, das zeigen sollte, wie so ein Zaehler
grundsaetzalich gestaltet werden kann.

flock wird spaeter eingefuehrt. In Lektion 10 . HTML Forumulare und
PHP sieht das dann so aus:

$fp = fopen($file, 'r+');
flock ($fp, LOCK_SH);
$count = fread($fp, 4096);
rewind ( $fp );
fwrite($fp, ++$count);
fflush ($fp);
flock ($fp, LOCK_UN);
fclose($fp);

Ich vermute, das wird dir auch nicht weiterhelfen.Um das Problem
einzugrenzen, wuerde ich das Konzept mit while ueber den kritischen
Wert hinauslaufen lassen. Dann sollte sich doch zeigen, ob der Counter
grundsaetzlich funktioniert, was ich vermute.

Franz-Josef

Dennis Kuenzel

unread,
Feb 25, 2011, 5:33:45 PM2/25/11
to
Hallo Jens,

ich vermute dein Problem liegt hier:

> $counts = file(PFAD."counter_files/count.txt");

file() liefert False zurück, wenn die Operation fehlgeschlagen ist. Das
kann durchaus mal vorkommen. Du testest zwar einen Schritt vorher ob die
Datei schreibbar ist, das kann sich beim file()-Aufruf aber schon wieder
geändert haben, wenn du parallele Zugriffe hast. Ein paralleler Prozess,
hat vielleicht gerade einen Schreib-lock für die Datei bekommen. Eine
klassische Race Condition. Du solltest dann zwar in der Zeile:

> $count = trim($counts[0]);

eine NOTICE bekommen, das der Index 0 in $counts nicht existiert, aber
ansonsten läuft dein Programm weiter und betrachtet $count dann als 0.
Am Ende sollte er einen Counter von 1 in die Datei schreiben.

Die Lösung dürfte sein, den lock auf das File schon vor dem lesen zu
holen, bzw. fürs lesen einen shared lock anzufordern.

Du solltest auch beachten das seit php 5.3.2 der lock nicht mehr
automatisch aufgehoben wird, wenn du fclose() aufrufst, dass musst du
dann via flock() explizit tun.

Bye,
Dennis

0 new messages