Tom: Daten im TXT-File werden überschrieben

Beitrag lesen

Hello lieber Christoph,

$inhalt = fopen("log.txt", "r+");
fputs($inhalt, "$newline\n");
fclose($inhalt);

Wie hier angegeben ("r+") steht der Dateizeiger an der Position 0 der Datei, also direkt am Anfang. Am Rest hat sich nichts bewegt, also wird überschrieben.
Wie machst Du es denn im Editor, wenn Du eine Zeile an den Anfang anfügen möchtest?
Mit dem Cursor an den Anfang und die Zeile einfügen. Der ganze Rest wandert dann nach unten, ist demnach vom Anfang um genausoviel weiter entfernt, wie die eingefügte Zeile lang ist. Und genau so mußt Du es auch hier machen:

[code]
$ip = $_SERVER['REMOTE_ADDR'];
$datum = date("d.m.Y H:i:s ");
$newline = $datum . $ip."\n";

$logfile = "log.txt";
// Öffnen der Datei zum Schreiben und Lesen
// Dateizeiger steht auf Anfang
// wenn sie nicht existiert gibt's einen Fehler
$fp      = fopen($logfile, "r+");

hier muss das exclusive Lock erwirkt werden!

// Einlesen der kompletten Datei in eine Variable
$str     = fread($fp, filesize ($logfile));
echo "str:" . $str . "<br>";
// Setzen der neuen Zeile vor den ganzen Rest
$out     = $newline.$str;
echo "out:" . $out . "<br>";
// Blockieren der Schreibzugriffe für alle anderen
// auf die Logdatei.

hier ist es schon zu spät!

#> flock($fp,2);

// Stellen des Dateizeigers auf den Anfang
fseek ($fp, 0,"SEEK_SET");
// Ausgabe des Dateiinhaltes
// fputs() setzt automatisch ein Zeilenendezeichen
fputs($fp, "$out");
// Freigabe der Schreibblockade
// (Nein, meine lieben Schriftsteller, das funktioniert
//  nicht bei euch)
flock($fp,3);
// Aufräumen
fclose($fp);

Damit sich nix falsches in Deinem Kopf oder im Archiv festsetzt:

Der Gesamte Veränderungsprozess muss durch exclusives Lock gebunden werden.
Also

öffnen
  sperren
  auslesen
  verändern
  zurückschreiben
  trimmen (falls der neue Inhalt kürzer als der alte wird)
  schließen (und damit auch automatisch entsperren)

Anderenfalls würde eine Gültigkeitslücke entstehen, die zur Inkonsistenz der Daten führen kann.

Die Parallelität von Prozessen muss bereits _vor_der_Absicht_des_Veränderns aufgehoben worden sein und durch das Lock serialisert werden.

Zur Verdeutlichung:

U1 liest - U1 verändert - U1 sperrt - U1 schreibt - U1 schließt
  U2 liest                          - U2 verändert                - U2 sperrt - U2 Schreibt - U2 schließt

Was steht nun in der Datei?

Da flock() unter PHP per default ein "Waitlock" ist, also solange das Script anhält, bis das Lock erfolgreich war (oder die Execute-Time überschritten wurde), würde der U2 das lediglich anhand einer kleinen Verzögerung merken, dass seine Datenmanipulation mit bereits veralteten Daten stattfand.

Harzliche Grüße vom Berg
esst mehr http://www.harte-harzer.de

Tom

--
Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
Nur selber lernen macht schlau