molily: Dateien schreiben und auslesen (Win32)

Hallo zusammen,

momentan bastle ich an einem simplen Kommentarsystem im Stil von crit.org. Meine Version ist jedoch ein wenig minimalistischer, benutzbarer und an meine Bedürfnisse angepasst.
Die Seitenkommentare werden in externen Dateien abgelegt, das erschien mir naheliegender als eine *SQL-Datenbank. Wenn ich die Datei später noch gzip-komprimiere, recht das vorerst für meine Zwecke.

Nun habe ich Probleme mit dem Schreiben und Lesen aus externen Dateien. Man schaue sich folgendes Testskript an:

<?php
$filename='test.txt';
$string=time().'|';

echo('<p>zu speichernder String: '.$string.' (Länge: '.strlen($string).')</p>');
echo('<p>Dateigröße vorm Speichern: '.@filesize($filename).' Bytes</p>');

echo('<p>String in Datei '.$filename.': ');

if (file_exists($filename)) {
 $file=fopen($filename, 'r');
 $dateiinhalt=fread($file, filesize($filename));
 fclose($file);
 echo($dateiinhalt.' (Länge: '.strlen($dateiinhalt).')</p>');
} else {
 echo('datei nicht gefunden</p>');
}

$neuerstring=$dateiinhalt.$string;

echo('<p>Speichere neuen String: '.$neuerstring.' (Länge: '.strlen($neuerstring).')</p>');

$filepointer=fopen($filename, 'w+');
fwrite($filepointer, $neuerstring);
fclose($filepointer);

echo('<p>String gespeichert in '.$filename.' (Größe: '.filesize($filename).' Bytes)</p>');

echo('<p>Lade String: ');

$file=fopen($filename, 'r');
$dateiinhalt=fread($file, filesize($filename));
fclose($file);
echo($dateiinhalt.' (Länge: '.strlen($dateiinhalt).')</p>');
?>

Angenommen die Datei existiert und enthält schon einen Zeitstring (Skript wurde schon einmal ausgeführt), dann ist Ausgabe ist bei mir (Apache/1.3.23 (Win32) PHP/4.1.3-dev) wie folgt:

zu speichernder String: 1023047510| (Länge: 11)
   Dateigröße vorm Speichern: 11 Bytes
   String in Datei test.txt: 1023047508| (Länge: 11)
   Speichere neuen String: 1023047508|1023047510| (Länge: 22)
   String gespeichert in test.txt (Größe: 11 Bytes)
   Lade String: 1023047508| (Länge: 11)

Da frage ich mich: wieso wird ein 22 Byte langer String problemlos in der Datei gespeichert, aber beim erneuten Auslesen in der selben Skriptinstanz ist sie nur 11 Byte groß (wie vorher)?
Nach Ende des Ausführens des Skripts ist die Datei ohne Frage mit dem richtigen String gefüllt, und die Größe ist auch in diesem Fall 22 Bytes.
Wenn man das Skript immer wieder ausführt, reiht es wie intendiert immer weiter Timestamps in der Datei aneinander.

Nun habe ich das o.g. hypercrit-Skript so konzipiert, dass, wenn ein Kommentar gespeichert werden soll, die Kommentardatei danach noch einmal ausgelesen wird, um die Kommentare anzuzeigen und die dokumentinternen Links zu den Kommentaren zu setzen.

Hat jemand Ideen oder Vorschläge? Ist vielleicht die Verwendung der binary safe fwrite und fread falsch?
Ich daran gedacht, dass es daran liegen könnte, dass im gegebenen Falle das Skript nicht nacheinander 'batch' interpretiert wird, sondern dass die Dateisystemoperationen nebeneinanderlaufen könnten... wirrer Erklärungsversuch; vielleicht könnte man sleep()s einbauen. :) Äußerst sinnfrei für Webseiten.

Grüße,
Mathias

  1. Angenommen die Datei existiert und enthält schon einen Zeitstring (Skript wurde schon einmal ausgeführt), dann ist Ausgabe ist bei mir (Apache/1.3.23 (Win32) PHP/4.1.3-dev) wie folgt:

    zu speichernder String: 1023047510| (Länge: 11)
       Dateigröße vorm Speichern: 11 Bytes
       String in Datei test.txt: 1023047508| (Länge: 11)
       Speichere neuen String: 1023047508|1023047510| (Länge: 22)
       String gespeichert in test.txt (Größe: 11 Bytes)
       Lade String: 1023047508| (Länge: 11)

    Da frage ich mich: wieso wird ein 22 Byte langer String problemlos in der Datei gespeichert, aber beim erneuten Auslesen in der selben Skriptinstanz ist sie nur 11 Byte groß (wie vorher)?

    Du mußt zwischen den Aufrufen von filesize() clearstatcache() aufrufen, weil die Daten von filesize() zwischengespeichert werden.

    Du rufst also in Deinem Skript einmal filesize() auf, die Funktion gibt 11 zurück und merkt sich diesen Wert. Später rufst Du beim zweiten Auslesen der Datei nochmal filesize() auf. Hier gibt die Funktion wieder den gespeicherten (jetzt falschen) Wert von 11 zurück.

    Dieses Verhalten ist auch in der Anleitung zu filesize() beschrieben.

    Gruß,
      soenk.e