Seitenzugriffszähler funktioniert nicht!
Yadgar
- php
High!
Ich habe mir vorhin einen einfachen Seitenzugrifsszähler (mit flock()-Seitensperrung) programmiert, der lokal auch prima funktioniert... aber als ich das Teil dann auf meinen (natürlich PHP-fähigen!) Webspace lud, kam mit einem Mal die Fehlermeldung "Öffnen von counter.dat fehlgeschlagen!".
Der Code von eigentlichem Zähler und aufrufender Seite sieht so aus:
[code=php]
<html>
<head>
</head>
<body>
<?php
$cfile = "counter.dat";
$fh = @fopen($cfile, "r+") or die("<br>Öffnen von <i>$cfile</i> fehlgeschlagen");
@flock($fh, LOCK_EX) or die("<br>Sperren von <i>$cfile</i> fehlgeschlagen");
$s = @fgets($fh, 7);
$count = (int)$s + 1;
$count = str_pad($count, 7);
@rewind($fh) or die("<br>Rücksetzen von <i>$cfile</i> fehlgeschlagen");
if (@fwrite($fh, $count)==-1)
{
die("<br>Schreiben in <i>$cfile</i> fehlgeschlagen");
}
echo $count;
@flock($fh, LOCK_UN) or die("<br>Unlock von <i>$cfile</i> fehlgeschlagen");
fclose ($fh) or die ("<br>Schließen von <i>$cfile</i> fehlgeschlagen");
?>
</body>
</html>
[/code]
bzw.
[code=php]
<html>
<head>
<title>GREENBOOK</title>
<style type="text/css">
<!--
h1, h2 { color:#ffe000; text-align:center }
-->
</style>
</head>
<body bgcolor="#a50030">
<br><br><br><br><br><br><br>
<h1>Hier entsteht der offizielle Website der Ökologisch-Demokratischen Republik<br>Bergisch-Afghanistan...</h1>
<br><br><br><br>
<h2>...und die heimorgeligste Datenbank diesseits des Khyberpasses!<h2>
<br><br><br>
<h1><blink>WATCH OUT!!!</blink></h1>
<p align="center" style="margin-top:150px; color:#ffe000">Diese Seite wurde seit dem 11. Dezember 2007 <b><?php include "counter.php"; /* echo "viele Milliarden"; */ ?></b> mal aufgerufen.</p>
</body>
</html>
[/code]
An irrtümlich nicht aktiviertem PHP auf dem Server kann es nicht liegen, da der (auskommentierte) Alternativtext "viele Milliarden" korrekt angezeigt wird! Woran dann?
Bis bald im Khyberspace!
Yadgar
Hallo!
Zugriffsrechte auf Datei am Server entsprechend setzen!
Hallo!
Zugriffsrechte auf Datei am Server entsprechend setzen!
Bingo! Und ich dachte erst, 754 wäre ausreichend... aber in diesem Fall muss natürlich alle Welt auf counter.dat schreibend zugreifen können!
Jedenfalls danke für den Tipp!
Bis bald im Khyberspace!
Yadgar
Hello,
Zugriffsrechte auf Datei am Server entsprechend setzen!
Bingo! Und ich dachte erst, 754 wäre ausreichend... aber in diesem Fall muss natürlich alle Welt auf counter.dat schreibend zugreifen können!
Nein, nicht "alle Welt", sondern eigentlich nur der PHP-Prozess.
Uneigentlich sollte auch Root (oder wie Dein Datensicherungsbneauftragter heißt) lesend zugreifen dürfen.
Und außerdem sollte die Zählerdatei natürlich auch vorhanden sein.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hello,
da passt sowieso einiges nicht zusammen.
<?php
$cfile = "counter.dat";
$fh = @fopen($cfile, "r+") or die("<br>Öffnen von <i>$cfile</i> fehlgeschlagen");
@flock($fh, LOCK_EX) or die("<br>Sperren von <i>$cfile</i> fehlgeschlagen");
$s = @fgets($fh, 7);
fgets iist nicht unbedingt die geeignete Lesemethode. Es werden hier bei Dir nur maximal sechs, ggf. auch nur fünf oder vier Nutzbytes gelesen, je nach Zeilenendezeichen und der Einstellung für auto_detect_line_endings.
Siehe Manual zu fgets http://de2.php.net/manual/de/function.fgets.php
$count = (int)$s + 1;
$count = str_pad($count, 7);
hier hast Du aber vermeintlich 7 Bytes bearbeitet.
ich würde Dir empfehlen, einfach mit fread zu lesen, aber zu überprüfen, ob Du die angeforderte Anzahl Bytes auch bekommen hast. Wenn nur eine Zahl drinsteht, brauchst Du auch strpad nicht zu quälen. Dann nimm lieber pack/unpack
http://de2.php.net/manual/de/function.pack.php
@rewind($fh) or die("<br>Rücksetzen von <i>$cfile</i> fehlgeschlagen");
if (@fwrite($fh, $count)==-1)
{
die("<br>Schreiben in <i>$cfile</i> fehlgeschlagen");
}
echo $count;
@flock($fh, LOCK_UN) or die("<br>Unlock von <i>$cfile</i> fehlgeschlagen");
Nicht vorher entsperren und dann schließen, sondern gleich schließen und dadurch entsperren.
Anderenfalls könnten schon wieder Fehler auftreten durch das implicit flush. Wenn Du unbedingt diskret entsprerren willst, musst Du vorher ein fflush($fh) aufrufen. Nicht verwechseln mit flush(), das ist für den Buffer der Standardausgabe.
fclose ($fh) or die ("<br>Schließen von <i>$cfile</i> fehlgeschlagen");
?>
Dein Script ist auch ein wenig paranoid.
Man sollte zwar Fehlerbehandlung durchführen, muss aber nicht jeden Fehler substantiiert melden. In diesem Falle würde ich dazu tendieren, zwischen zwei Fehlern (= drei Fehlernummern) zu unterscheiden. Genereller Zugriffsfehler und Erfolg/Misserfolg der Gesamtoperation, wobei man dann die Konvention hätte, das eine 0 als Rückgabewert Erfolg bedeutet.
Also das Ganze als Funktion aufbauen, die selber NICHTS auf die Standardausgabe schreibt!
<p><?php include "counter.php"; /* echo "viele Milliarden"; */ ?></b> mal aufgerufen.</p>
Das Include sollte keine Ausgaben tätigen.
Es sollte die Funktionen bereitstellen, die Du dann in dem tatsächlichen Anzeigescript nutzen willst/kannst.
Außerdem sind Auslesen und Beschreiben zwei unterschiedliche Vorgänge, die man auch hübsch getrennt halten sollte in seinem Funktionsstamm. Auslesen wird i.d.R. viel häufiger vorkommen, als Beschreiben. Auslesen muss daher (bei größeren Scripten) also "geschwindigkeitsoptimiert" sein, wöhrend Beschreiben doch eher "sicherheitsoprimiert" sein sollte.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom