faruk: Daten im TXT-File werden überschrieben

Ich möchte, dass jede neue Zeile im txt-file oben über dem inhalt geschrieben wird.
Stattdessen habe ich immer nur eine Zeile mit den letzten Daten im txt-file.

<?php

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

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

?>

Was mache ich falsch?

  1. hi,

    $inhalt = fopen("log.txt", "r+");

    Schau dir im Manual an, was "r+" als zweiter Parameter von fopen bedeutet - und welche Alternativen es noch gibt.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
  2. Hi,

    Ich möchte, dass jede neue Zeile im txt-file oben über dem inhalt geschrieben wird.

    das kannst Du erreichen, indem Du

    • die Daten am Ende der Datei anhängst und anders herum ausgibst,
    • die gesamte Datei komplett ausliest und, beginnend mit der neuen Zeile, komplett neu schreibst,
    • die Daten anhängst und den Monitor umdrehst, oder
    • eine Datenbank verwendest und die Daten entsprechend sortieren lässt.

    Kein mir bekanntes Dateisystem kann das von Dir Geforderte leisten.

    Stattdessen habe ich immer nur eine Zeile mit den letzten Daten im txt-file.

    Natürlich. Wer etwas Unmögliches versucht, braucht sich über unerwünschte Ergebnisse nicht zu wundern.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hello,

      Ich möchte, dass jede neue Zeile im txt-file oben über dem inhalt geschrieben wird.

      das kannst Du erreichen, indem Du

      [...]

      • die Daten anhängst und den Monitor umdrehst, oder

      Könntest Du (mal eben so aus dem Handgelenk) die Abbildungsfunktion dafür bekanntgeben? *gg*
      Die würde mich schon interessieren. Muss man da den Zeichensatz auch umschalten?

      *scnr*
      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
  3. Hi,

    Ich möchte, dass jede neue Zeile im txt-file oben über dem inhalt geschrieben wird.
    Stattdessen habe ich immer nur eine Zeile mit den letzten Daten im txt-file.

    Das ist auch korrekt so:

    $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:

      
    $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+");  
    // 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.  
    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);  
    
    

    Obiger Code ist _nur_ zur Veranschaulichung und _nicht_ für den produktiven Einsatz geeignet!

    so short

    Christoph Zurnieden

    1. 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