Marco: In Datei schreiben

Moin,

ich habe ein Problem mit einem winzigen PHP-Skript, das ein Wort aus einer Datei entfernen soll:

<?php

$datei = fopen("test.txt","r+");

while(!feof($datei)) {$inhalt .= fgets($datei,1000);}

rewind($datei);

//Position 1

$inhalt = ereg_replace("test", "", $inhalt);

//Position 2

fwrite($datei, $inhalt);

fclose($datei);

?>

Die Datei test.txt enthält nur das Wort "test".
Wenn ich mir im Skript die Variable $inhalt ausgeben lasse, wird Position 1 das Wort "test" ausgegeben, an Position 2 gar nichts.
Wo liegt der Fehler, dass der Inhalt der Datei trotzdem nicht geändert wird?

Danke,

Marco

  1. echo $begrüßung;

    $datei = fopen("test.txt","r+");

    $inhalt = '';

    fwrite($datei, $inhalt);
    fclose($datei);

    Wo liegt der Fehler, dass der Inhalt der Datei trotzdem nicht geändert wird?

    Zusammengefasst sieht dein Problem wie oben aus. Ändere die Zuweisung auf

    $inhalt = 'f';

    und schau dir nun das Ergebnis in der Datei an.

    echo "$verabschiedung $name";

  2. Moin,

    ich habe jetzt den Denkfehler gefunden:

    Der Dateizeiger steht ja am Anfang und schreibt von dort aus. Da nichts geschrieben wird, wird der Inhalt auch nicht überschrieben. Wie kann ich mein Problem denn dann lösen?

    Natürlich könnte ich die Datei löschen und mit dem neuen Inhalt neu anlegen, was aber ziemlich aufwendig wäre. Gibts eine andere Lösung um einen Teil der Datei zu löschen??

    MfG,
    Marco

    1. echo $begrüßung;

      Natürlich könnte ich die Datei löschen und mit dem neuen Inhalt neu anlegen, was aber ziemlich aufwendig wäre. Gibts eine andere Lösung um einen Teil der Datei zu löschen??

      Um Teile aus einer Datei zu löschen oder auch Teile einzufügen muss man den Rest der Datei neu schreiben. Ein automatisches Vor- oder Zurückgeschiebe von Dateiteilen findet nicht statt.

      echo "$verabschiedung $name";

      1. Hi,
        Es ist mir klar, dass ich den Rest neu schreiben muss. Deshalb kommt auch der gesamte Inhalt der Datei in die Variable $inhalt. Ich möchte dann mit dem geänderten Inhalt den neuen überschreiben. Das Problem ist nur, dass wenn der neue Inhalt kürzer ist, der alte Inhalt zum Teil stehen bleibt. Mir fällt nur ein, dass ich die Datei löschen könnte und komplett neu anlegen. Aber gibt es keinen anderen Weg den gesamten Inhalt zu entfernen und mit dem neuen zu ersetzen?

        MfG,
        Marco

        1. gudn tach!

          Das Problem ist nur, dass wenn der neue Inhalt kürzer ist, der alte Inhalt zum Teil stehen bleibt. Mir fällt nur ein, dass ich die Datei löschen könnte und komplett neu anlegen. Aber gibt es keinen anderen Weg den gesamten Inhalt zu entfernen und mit dem neuen zu ersetzen?

          [link:http://de3.php.net/manual/en/function.ftruncate.php@title=ftruncate]($datei, strlen($inhalt));

          prost
          seth

        2. echo $begrüßung;

          Das Problem ist nur, dass wenn der neue Inhalt kürzer ist, der alte Inhalt zum Teil stehen bleibt.

          Merke dir die aktuelle Position, gehe zum Dateianfang und schneide die Datei auf die gemerkte Länge zurecht.

          echo "$verabschiedung $name";

  3. Hallo, Marco,

    versuch's mal so (ungetestet) ...

    $file='test.txt';
    $datei=fopen($file,'r+');
    $inhalt=fread($datei,filesize($file));
    $inhalt=str_replace('test','',$inhalt);
    fwrite($datei,$inhalt)
    fclose($datei);

    Grüße,

    Sebastian

    1. Hallo Sebastian,

      danke für deine Antwort, aber leider hilft sie mir nicht weiter. Da taucht das Problem auf was ich gerade eben genannt habe. Der neue Inhalt wird einfach hintendrangehängt. Wenn ich ein rewind($datei); einbaue wird der alte Inhalt nur zum Teil ersetzt, wenn der neue kürzer ist. Dann bleibt nämlich der hintere Teil des alten Inhalts stehen.

      MfG,
      Marco

      1. Hallo Marco,

        Da taucht das Problem auf was ich gerade eben genannt habe. Der neue Inhalt wird einfach hintendrangehängt. Wenn ich ein rewind($datei); einbaue wird der alte Inhalt nur zum Teil ersetzt, wenn der neue kürzer ist. Dann bleibt nämlich der hintere Teil des alten Inhalts stehen.

        Wozu brauchst Du denn das "rewind"? Wenn Du es so machst wie in meinem Beispiel sollte eigentlich die ganze Datei neu geschrieben werden ...

        Grüße,

        Sebastian

        1. gudn tach!

          Wenn Du es so machst wie in meinem Beispiel sollte eigentlich die ganze Datei neu geschrieben werden ...

          nein, siehe fopen.
          du liest damit die datei in $inhalt ein und haengst anschliessend nix (bzw. eine leerzeile) hinten dran.

          prost
          seth

          1. Hallo, Seth,

            Wenn Du es so machst wie in meinem Beispiel sollte eigentlich die ganze Datei neu geschrieben werden ...

            nein, siehe fopen.
            du liest damit die datei in $inhalt ein und haengst anschliessend nix (bzw. eine leerzeile) hinten dran.

            Dann nimm "w+" (s.u.: truncate the file to zero) ...

            Grüße,

            Sebastian

            mode Description
            'r' Open for reading only; place the file pointer at the beginning of the file.
            'r+' Open for reading and writing; place the file pointer at the beginning of the file.
            'w' Open for writing only; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
            'w+' Open for reading and writing; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.

            1. gudn tach!

              Wenn Du es so machst wie in meinem Beispiel sollte eigentlich die ganze Datei neu geschrieben werden ...

              nein, siehe fopen.
              du liest damit die datei in $inhalt ein und haengst anschliessend nix (bzw. eine leerzeile) hinten dran.

              Dann nimm "w+" (s.u.: truncate the file to zero) ...

              dann wuerde aber der dateiinhalt geloescht, den der op ja eigentlich modifizieren wollte.

              eine kombination, erst "r", dann "w", waere moeglich, aber ich vermute, dass die ftruncate-methode, die jetzt bereits zweimal vorgeschlagen wurde, besser ist.

              prost
              seth

              1. Hallo, Seth,

                Dann nimm "w+" (s.u.: truncate the file to zero) ...
                dann wuerde aber der dateiinhalt geloescht, den der op ja eigentlich modifizieren wollte.
                eine kombination, erst "r", dann "w", waere moeglich, aber ich vermute, dass die ftruncate-methode, die jetzt bereits zweimal vorgeschlagen wurde, besser ist.

                Wenn es funktioniert, ist es ja gut - aber warum so kompliziert?

                $file='test.txt';
                $datei=fopen($file,'w+');
                $inhalt=fread($datei,filesize($file));
                $inhalt=str_replace('test','',$inhalt);
                fwrite($datei,$inhalt)
                fclose($datei);

                Bei dieser Methode (s.o.) wird die Datei zuerst zum Lesen und Schreiben geöffnet, dann der Inhalt der Datei in eine Variable eingelesen, dann ein String in der Variable ersetzt (aus Performancegründen ohne reguläre Ausdrücke), dann der Inhalt der Variable wieder in die Datei geschrieben (wobei der Originalinhalt ersezt wird) und zu guter Letzt wird die Datei geschlossen.

                Grüße,

                Sebastian

                1. echo $begrüßung;

                  ich vermute, dass die ftruncate-methode, die jetzt bereits zweimal vorgeschlagen wurde, besser ist.
                  Wenn es funktioniert, ist es ja gut - aber warum so kompliziert?

                  Deine beiden Vorschläge sind einfach fehlerhaft.

                  $file='test.txt';
                  $datei=fopen($file,'w+');

                  Die Datei wird geöffnet, w+ bewirkt, dass der Dateizeiger auf den Anfang gestellt und der Rest der Datei abgeschnitten wird.

                  $inhalt=fread($datei,filesize($file));

                  Es gibt nun nichts mehr zu lesen, weil bereits alles abgeschnitten wurde.
                  In deinem ersten Vorschlag wurde die Datei mit r+ geöffnet. Der Dateizeiger stand dabei am Anfang. Nach dem fread() steht er nun am Dateiende.

                  $inhalt=str_replace('test','',$inhalt);
                  fwrite($datei,$inhalt)

                  Und an dieses Dateiende schreibst du nun die geänderten Daten.

                  echo "$verabschiedung $name";

                  1. Hallo, dedlfix,

                    Deine beiden Vorschläge sind einfach fehlerhaft.

                    mag sein, war ja auch ungetestet. Dann musst Du die beiden Methoden eben kombinieren, d.h. zuerst zum Lesen öffnen, dann zum Schreiben öffnen so daß alte Inhalte gelöscht werden.

                    So hab' ich es schon tausendmal gemacht und zwar mit folgenden Funktionen ...

                    function readFromFile($file)
                    {
                    $str=0;
                    if($file!=''&&file_exists($file)&&is_file($file)&&is_readable($file)) {
                    $fp=fopen($file,'r');
                    flock($fp,LOCK_SH);
                    $str=fread($fp,filesize($file));
                    flock($fp,LOCK_UN);
                    fclose($fp);
                    }
                    return $str;
                    }

                    function writeToFile($file,$str)
                    {
                    $success=0;
                    if($file!='') {
                    $fp=fopen($file,'w');
                    flock($fp,LOCK_EX);
                    if(fwrite($fp,$str))$success=1;
                    flock($fp,LOCK_UN);
                    fclose($fp);
                    return $success;
                    }
                    }

                    Grüße,

                    Sebastian

  4. Hello,

    Die Datei test.txt enthält nur das Wort "test".
    Wenn ich mir im Skript die Variable $inhalt ausgeben lasse, wird Position 1 das Wort "test" ausgegeben, an Position 2 gar nichts.
    Wo liegt der Fehler, dass der Inhalt der Datei trotzdem nicht geändert wird?

    Dateien werden durch einfaches Beschreiben nicht kürzer.
    Das was vorher dastand, steht auch hinterher noch da, wenn es nicht _über_schrieben wurde.

    Harzliche Grüße vom Berg
    http://www.annerschbarrich.de

    Tom

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