Steffen Reinig: fopen

Hi,

habe ein kleines Problem! Habe angefangen jetzt ein kleines Guestbook zu schreiben. Jetzt funktionierte das GB soweit, nur das er die neuen Einträge unten positionierte astadt oben. Für unten nutzte ich den Code:

$datei = fopen("eintraege.txt","a");
$eintrag = ereg_replace("\n","<br>",$eintrag);
$eintrag = stripslashes($eintrag);
$eintrag = wordwrap($eintrag, 62, "<br>", 1);
$daten =  "<table width=350px><tr><td style="text-align: justify"> <b>$name</b> {<a href=mailto:$email>$email</a>/<a href=$url target=_blank onfocus=this.blur(); return true;>$url</a>} <br> $eintrag <br>\n\n </td></tr></table>";
fwrite($datei,$daten);
fclose($datei);

Jetzt dachte ich mir naja da die option "a" bei fopen den Zeiger ans Ende stellt müßte r+ den zeiger nach vorne Stellen!

Ok jetzt hab ich aber das Problem, dass er den davor gespeicherten Text überschreibt ... :-/

Dann habe ich nach einer anderen Lösung ausschau gehalten und das zusammengefriemelt:

$datei = fopen("eintraege.txt","r+");
$inhalt = fread($datei,filesize("eintraege.txt"));
$eintrag = ereg_replace("\n","<br>",$eintrag);
$eintrag = stripslashes($eintrag);
$eintrag = wordwrap($eintrag, 62, "<br>", 1);
$daten =  "<table width=350px><tr><td style="text-align: justify"> <b>$name</b> {<a href=mailto:$email>$email</a>/<a href=$url target=_blank onfocus=this.blur(); return true;>$url</a>} <br> $eintrag <br>\n\n </td></tr></table>";
$insgesammt = $daten . $datei;
fclose($datei);
$datei = fopen("eintraege.txt", "w");
fwrite($datei,$insgesammt);
fclose($datei);

Jetzt speichert er immer noch nur den neusten Beitrag und die anderen Fallen weg ... und am Ende steht Resource id #1

Wie bekomme ich diesen Fehler weg?

mfg Steffen

  1. Moin!

    Jetzt dachte ich mir naja da die option "a" bei fopen den Zeiger ans Ende stellt müßte r+ den zeiger nach vorne Stellen!

    Ok jetzt hab ich aber das Problem, dass er den davor gespeicherten Text überschreibt ... :-/

    Logisch. Wenn du vorne etwas anfügen wolltest, müßte der Computer auf der Festplatte für jedes gespeicherte Byte die gesamte Datei genau ein Byte nach hinten schieben, damit neuer Platz entsteht - also wahnsinnig viel kopieren. Das macht er aber nicht.

    Hinten anhängen ist dagegen ganz einfach: Datei öffnen, das Ende finden, und weiterschreiben.

    Lösung: Wenn du in einer Datei vorne was davorhängen willst, mußt du die gesamte Datei einlesen, das gewünschte davorhängen und den eingelesenen Rest dahinterhängen. Wahlweise kannst du auch die bisherige Datei umbenennen, eine neue Datei mit dem alten Namen anlegen, zuerst das Neue reinschreiben und dann den Inhalt der umbenannten Datei auslesen und in die neue Datei schreiben. Am Ende löschst du die umbenannte Datei.

    Beide Methoden sind nicht wahnsinnig performant - bei einem Gästebuch mit grob geschätzt einem Eintrag pro Tag dürfte das aber kein Problem sein.

    Die Alternative wäre, in der Datei einfach nur hinten dranzuhängen, und bei der Ausgabe umgekehrt zu sortieren - wäre aber auch nicht unbedingt besser, weil Gästebücher in der Regel mehr gelesen als beschrieben wären - allerdings kann das Sortieren im Speicher ablaufen, was durchaus schneller geht, als auf der Festplatte zu operieren.

    - Sven Rautenberg

    --
    "Bei einer Geschichte gibt es immer vier Seiten: Deine Seite, ihre Seite, die Wahrheit und das, was wirklich passiert ist." (Rousseau)
    1. Hallo!

      Die Alternative wäre, in der Datei einfach nur hinten dranzuhängen, und bei der Ausgabe umgekehrt zu sortieren - wäre aber auch nicht unbedingt besser, weil Gästebücher in der Regel mehr gelesen als beschrieben wären - allerdings kann das Sortieren im Speicher ablaufen, was durchaus schneller geht, als auf der Festplatte zu operieren.

      Braucht man ja gar nicht, oder?

      $data = file("gb.txt");
      for ($i=count($data); $i>0; $i--) {
          echo trim($data[$i])."<hr />";
      }

      da wird doch dann nichts sortiert, oder?

      Grüße
      Andreas

    2. Moin!

      Jetzt dachte ich mir naja da die option "a" bei fopen den Zeiger ans Ende stellt müßte r+ den zeiger nach vorne Stellen!

      Ok jetzt hab ich aber das Problem, dass er den davor gespeicherten Text überschreibt ... :-/

      Logisch. Wenn du vorne etwas anfügen wolltest, müßte der Computer auf der Festplatte für jedes gespeicherte Byte die gesamte Datei genau ein Byte nach hinten schieben, damit neuer Platz entsteht - also wahnsinnig viel kopieren. Das macht er aber nicht.

      Hinten anhängen ist dagegen ganz einfach: Datei öffnen, das Ende finden, und weiterschreiben.

      Lösung: Wenn du in einer Datei vorne was davorhängen willst, mußt du die gesamte Datei einlesen, das gewünschte davorhängen und den eingelesenen Rest dahinterhängen. Wahlweise kannst du auch die bisherige Datei umbenennen, eine neue Datei mit dem alten Namen anlegen, zuerst das Neue reinschreiben und dann den Inhalt der umbenannten Datei auslesen und in die neue Datei schreiben. Am Ende löschst du die umbenannte Datei.

      - Sven Rautenberg

      Ja, aber wieso funktioniert die 2te Möglichkeit nicht? Ich speicher ja zuerst die die neue eingabe und sage $insgesammt = $neu . $alt und speicher es dann wieder in der Datei ab ... und was heißt das die komische Meldung mit der id1?

      1. Moin!

        Vollquottel! http://learn.to/quote

        Ja, aber wieso funktioniert die 2te Möglichkeit nicht? Ich speicher ja zuerst die die neue eingabe und sage $insgesammt = $neu . $alt und speicher es dann wieder in der Datei ab ... und was heißt das die komische Meldung mit der id1?

        Logisch: Das Dateihandle steht in $datei drin und bezeichnet eine interne Struktur zum Dateizugriff, welche als "id1" ausgegeben wird. Der Datei_inhalt_ steht hingegen in $eintrag. _Der_ wird aber nicht gerettet, sondern nach Ende des Skripts vergessen.

        - Sven Rautenberg

        --
        "Bei einer Geschichte gibt es immer vier Seiten: Deine Seite, ihre Seite, die Wahrheit und das, was wirklich passiert ist." (Rousseau)
    3. Hallo Sven,

      Logisch. Wenn du vorne etwas anfügen wolltest, müßte der Computer auf der Festplatte für jedes gespeicherte Byte die gesamte Datei genau ein Byte nach hinten schieben, damit neuer Platz entsteht - also wahnsinnig viel kopieren. Das macht er aber nicht.

      Das reizt mich doch schon wieder zur ketzerischen Äußerungen...
      Bei der ganzen PC-Entwicklung hätte ja auch mal einer ein anständiges Dateisystem erfinden können, bei dem das geht. Ist ja schließlich nicht mehr Aufwand, als hinten einen Block anzuhängen, der dann nur zu x% gefüllt wird. Einfach die Kette vorne im FAT auftrennen und was reinschreiben. Muss eben zusatzlich zur Dateilänge auch ein Dateianfang (OFB = Offset in First Block of Chain of FAT) geführt werden.

      Hinten anhängen ist dagegen ganz einfach: Datei öffnen, das Ende finden, und weiterschreiben.

      Und was hälts Du von der Speicherung in einem Baum? Den kann man zur Einfachheit ja am Anfang auch als einzelne Dateien sortieren, da er bei einem Gästebuch eh nur linear ist.

      Liebe Weihnachtsgrüße aus Brausnchweig

      Tom

  2. würde vielleicht das ocmmande fseek was nützen wenn ja wie müßte ich das denn anwenden?

    mfg steffen