cr: zeilenweise ersetzen

hallo,

ich habe folgende txt-datei

1|chris|Frankfurt
2|Tina|Hannover
3|Stefan|Dresden

wie kann ich jetzt den eintrag von tina ort hannover auf münchen ändern mittels php?

danke und grüße cliff

  1. Gude,

    machs doch mit split()
    dann splitest du die werte anhand von | und kannst dann diese abändern und wieder speichern.

    Gruß
    cr2

    1. hallo cr2,

      danke.

      aber ich will dass z.b. tina das selber ändern kann, aber sie die anderen informationen nicht sieht (auch nicht im quelltext versteckt)

      mir fehlt da grad der faden wie ich anfang...

      grüße cr

      1. hallo cr2,

        danke.

        aber ich will dass z.b. tina das selber ändern kann, aber sie die anderen informationen nicht sieht (auch nicht im quelltext versteckt)

        mir fehlt da grad der faden wie ich anfang...

        grüße cr

        Wenn der User(Tina) sich selbst anlegen kann, sollte es über die(fast) gleiche funktion auch gehen, die Daten zu ändern.
        und zwar wie vorgänger schrieb, mit str_replace.

    2. Gude,

      machs doch mit split()
      dann splitest du die werte anhand von | und kannst dann diese abändern und wieder speichern.

      Gruß
      cr2

      Ich habe das so verstanden, das er die zusammengehörigkeit von:

      2 und Tina und Hannover Braucht, um nicht eventuell einen anderen Wert bei dem zufälliger weise auch Hannover steht zu ändern.

      Ich würde die Datei in String einlesen, und den gesamten Wert suchen und ersetzten. mit replace oder sowas.

  2. Hallo cr,

    ich habe folgende txt-datei

    1|chris|Frankfurt
    2|Tina|Hannover
    3|Stefan|Dresden

    wie kann ich jetzt den eintrag von tina ort hannover auf münchen ändern mittels php?

    Mit einer geschickten Kombination aus fopen, file und str_replace.

    Beste Grüße
    Richard

    --
    ~§%+
  3. hallo,

    ich habe folgende txt-datei

    1|chris|Frankfurt
    2|Tina|Hannover
    3|Stefan|Dresden

    wie kann ich jetzt den eintrag von tina ort hannover auf münchen ändern mittels php?

    öffne die Datei mir fopen(), dann liest du den Inhalt mittels file_get_contents(), dann splittest du den Inhalt mittel list() und split(), dann ändernst du die Felder, speichere dann alles per fwrite() und schließe die Datei mit fclose().

    Also so:

    $datei = "Datei";
    $datei_handle = fopen("$datei", 'a');
    $datei_inhalt = file_get_contents( $datei );
    list($count[], $name[], $ort[]) = split("|", datei_inhalt, 3);
    $ort[1] = "münchen";
    for ($i=0; $i<3; $i++) {
     $to_save = "$count[$i]|$name[$i]|$ort[$i]";
    }
    fwrite($datei_handle, "$to_save");
    fclose($datei_handle);

    Nur noch die for()-Schleife dynamisch machen.

    1. Hello,

      öffne die Datei mir fopen(), dann liest du den Inhalt mittels file_get_contents(), dann splittest du den Inhalt mittel list() und split(), dann ändernst du die Felder, speichere dann alles per fwrite() und schließe die Datei mit fclose().

      Wenn eine Datei mit file_get_contents() gelesen werden soll, muss sie nicht vorher mit fopen() gelesen werden.

      File_get_contents() eignet sich nur für "ungesichertes Lesen", da man sie nicht mit einem gebundenen Lock belegen kann.

      Das gleiche gilt für file() (und alle anderen namensbasierten Schreib- und Lesefunktionen), was dann hier wenigstens noch geeignet wäre, als file_get_contents(), aber immer noch zu Schmuddelprogrammierung führt.

      also besser so:

      define('CRLF', "\n");   ## Zeilenende-Zeichen muss zum System passen
        define('FELDTRENNER','|');

      $datei_name   = "Datei";
        $datei_handle = fopen("$datei_name", 'rw');
        $datei_lock   = flock($dateihandle, LOCK_EX);
        $datei_laenge = filesize($datei_name);
        $datei_inhalt = fread($datei_handle, $datei_laenge);
        $datei_array  = explode(CRLF, $datei_inhalt);

      foreach($datei_array as $satznummer => $datensatz)
        {
          $datei_array[$satznummer] = explode(FELDTRENNER,$datensatz);

      if($datei_array[$satznummer][0] == '2' and
             $datei_array[$satznummer][1] == 'Tina' and
             $datei_array[$satznummer][2] == 'Hannover')
          {
            $datei_array[$satznummer][2] = 'München';
          }
        }

      foreach($datei_array as $satznummer => $datensatz)
        {
          $datei_array[$satznummer] = implode(FELDTRENNER,$datensatz);
        }

      $datei_inhalt = implode(CRLF, $datei_array);

      fseek($datei_handle, 0, SEEK_SET);
        fwrite($datei_handle, $datei_inhalt);
        ftruncate($datei_handle, $length($datei_inhalt);
        fclose($datei_handle);

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

      Tom

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

      1. Hello,

        kleine Erläuterung und Fehlerkorrektur. length() gibt es nicht in PHP...

        also besser so:

        define('CRLF', "\n");       ## Zeilenende-Zeichen muss zum System passen
          define('FELDTRENNER','|');  ## Trennzeichen zwischen den Datenfeldern

        ## darf in den Daten nicht vorkommen!

        $datei_name   = "Datei";
          $datei_handle = fopen("$datei_name", 'rw');          ## Datei öffnen
          $datei_lock   = flock($dateihandle, LOCK_EX);        ## Dateisperre beantragen und solange

        ## warten bis es klappt

        $datei_laenge = filesize($datei_name);               ## Dateigröße ermitteln
          $datei_inhalt = fread($datei_handle, $datei_laenge); ## Datei komplett auslesen
          $datei_array  = explode(CRLF, $datei_inhalt);        ## ausgelesene Datei in Array umwandeln
                                                               ## ein Element pro Datensatz
          foreach($datei_array as $satznummer => $datensatz)   ## alle Elemente des Arrays
          {
            $datei_array[$satznummer] = explode(FELDTRENNER,$datensatz);  ## in Felder aufteilen

        if($datei_array[$satznummer][0] == '2' and         ## gleichzeitig nach gewünschtem
               $datei_array[$satznummer][1] == 'Tina' and      ## Inhalt fahnden
               $datei_array[$satznummer][2] == 'Hannover')
            {
              $datei_array[$satznummer][2] = 'München';        ## Bei Treffer ersetzen
            }
          }

        foreach($datei_array as $satznummer => $datensatz)   ## Felder wieder zu Zeilen verpacken
          {
            $datei_array[$satznummer] = implode(FELDTRENNER,$datensatz);
          }

        $datei_inhalt = implode(CRLF, $datei_array);         ## Zeilen wieder zu String verpacken

        fseek($datei_handle, 0, SEEK_SET);                   ## Satzzeiger an den Dateianfang

        ## zurückstellen

        fwrite($datei_handle, $datei_inhalt);                ## Dateiinhalt wegschreiben

        ftruncate($datei_handle, $strlen($datei_inhalt);     ## evtl. überstehenden Rest der alten
                                                                 ## Datei abschneiden

        fclose($datei_handle);                               ## Datei schließen und Lock freigeben

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

        Tom

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

  4. danke für die vielen tipps,

    habe jetzt mal von allem etwas und es funtkioniert auch (fast) so wie ich es will.

    habe die txt noch etwas abgeändert

    chris|Frankfurt
    Tina|Hannover
    Stefan|Dresden
    _______________

    $datei_handle = file(datei.txt);
    $suchen = "Hannover";
    $ersetzen = "München";
    $user = "Tina";

    foreach($datei_handle as $zeile)
    {
    $zeile = explode("|", $zeile);
    if($zeile[0] == $user)
    {
    $zeile[1] = str_replace($suchen, $ersetzen, $zeile[1]);
    }
    $zeile = implode("|", $zeile);

    $datei = fopen("datei.txt", 'a');
    fwrite($datei, $zeile);
    fclose($datei);
    }

    so ich hoffe ich habe alles richtig abgeschrieben...wenn ich das so wie oben mach, dann schreibt mir php an den vorhandenen eintrag den bearbeiteten eintrag so wie er sein soll. leider löscht php den alten eintrag nicht. wenn ich fopen 'w' zuweise, dann wird komischerweise in der txt nur der letzte eintrag des alten eintrags gespeichert, der rest ist weg...seht ihr in diesem einfachen beispiel den fehler?

    danke und grüße

    cr

    1. Hello,

      habe jetzt mal von allem etwas und es funtkioniert auch (fast) so wie ich es will.

      Glaub ich nicht :-)

      habe die txt noch etwas abgeändert

      chris|Frankfurt
      Tina|Hannover
      Stefan|Dresden
      _______________

      $datei_handle = file(datei.txt);     ## file() liefert kein Handle, sondern
                                             ## den Inhalt der Datei in einem Zeilenarray

      $suchen = "Hannover";
      $ersetzen = "München";
      $user = "Tina";

      foreach($datei_handle as $zeile)
      {
        $zeile = explode("|", $zeile);
        if($zeile[0] == $user)
        {
        $zeile[1] = str_replace($suchen, $ersetzen, $zeile[1]);

      ## das funktioniert zwar, ist aber eigentlich nicht genau das, was Du willst
        ## es wird hier das gesuchte Wort ersetzt, nicht aber der komplette Inhalt der Datenzelle
        ## Dass der hier zufällig identisch ist, liegt an der Art Deiner Suche.
        ## Wenn Du mal anders suchst, dann kann sowas in die Hose gehen, wenn Du nicht daran denkst
        ## auch die Ersetzungsfunktion anzupassen.

      }
        $zeile = implode("|", $zeile);

      $datei = fopen("datei.txt", 'a');

      Der Öffnungsmodus 'a' steht für "Anhängen" oder "Append".

      Du willst aber sicher die gesamte alte mit der geänderten Datei überschreiben.

      Daür müsstest Du den Öffnungsmodus 'w' nehmen.

      fwrite($datei, $zeile);
        fclose($datei);
      }

      Wenn Du nun aber einfach 'a' gegen 'w' ersetzt, dann hättest Du nur noch die letzte Zeile in der Datei stehen.

      Du müsstest die Datei zum Schreiben also _vor_ Deiner Schleife öffnen und _hinter_ _dem_ _Ende_ ersxt wieder schließen.

      $inhalt = file()
        ...

      $handle = fopen(...,'w');

      foreach()
        {

      ...

      fwrite($handle,$verpacktezeile)
        }

      fclose()

      Außerdem hat Deine Methode so eine empfindliche Schwachstelle.
      Wenn Du die Datei eingelesen hast, und öffnest sie dann mittels fopen($dateiname,'w'), dann ist die alte Datei weg. Wenn Dein Script nun nicht ordnungsgemäß arbeitet, bleibt sie kaputt oder verschwunden...

      Außerdem darf dieses Script nur ein User (ein Prozess) zur gleichen Zeit verwenden.
      Wenn Du das nicht sicherstellen kannst, gefährdest Du auch Deine Daten.

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

      Tom

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

      1. hello,

        danke für die vielen hinweise.

        um das problem mit dem suchen zu umgehen/beheben wäre es doch auch möglich, dass ich einfach statt nach dem wert hannover zu suchen den inhalt von $zeile[1] des entsprechenden users tina lösche...ohne zu schauen was drin ist...denn es ist immer ein ort drin...und dann münchen einfach reinschreib...aber wie leere ich das array ohne es zu entfernen?

        das mit dem fopen "w" werd ich so mal testen, hab meinen laptop aber schon aus...

        ich werde noch weiteres einbauen zur erhöhung der sicherheit wie die sperre dder datei und auch das anlegen einer temp-datei, die erst gelöscht wird, wenn der vorgang erfolgreich war, mir geht es zuerst um das prinzip der funktion damit dies, wenn auch in schlechten stil, funktioniert.

        grüße cr

        1. Hello,

          um das problem mit dem suchen zu umgehen/beheben wäre es doch auch möglich, dass ich einfach statt nach dem wert hannover zu suchen den inhalt von $zeile[1] des entsprechenden users tina lösche...ohne zu schauen was drin ist...denn es ist immer ein ort drin...und dann münchen einfach reinschreib...aber wie leere ich das array ohne es zu entfernen?

          Das Suchen sollte kein Problem sein, außer, dass Du da ggf. die Groß-/Kleinschreibung ausblenden solltest.

          Für das Ersetzen solltest Du dann einfach den Inhalt des betroffenen Array-Elementes überschreiben, anstatt ihn mit der Replace-Funktion zu behandeln.

          Wenn du jetzt schon weißt, das die Datei nicht sehr groß wird, könntest Du auch mit

          serialize()    http://de.php.net/manual/de/function.serialize.php
          und
            unserialize()  http://de.php.net/manual/en/function.unserialize.php

          arbeiten

          Da könntest Du dann das ganze zweidimensionale Array abspeichern, in dem der Index als ID benutzt wird. Da es jeden Index im Array (in der Dimension) nur einmal geben kann, wäre das dann gleich Dein Schlüssel für den Zugriff. Du könntest nach dem Laden und Deserialisieren über den Schlüssel also sofort auf das Element in der betroffenen Zeile (Subarray) zugreifen.

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

          Tom

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

          1. hello,

            es werden schon eher viele daten werden. welche funktion nutze ich zum überschreiben einen arrays?

            oder soll ich mit php das array auslesen und dann den alten werd mit dem neuen durch replace ersetzen?

            danke und gruß cr

            1. Hello,

              oder soll ich mit php das array auslesen und dann den alten werd mit dem neuen durch replace ersetzen?

              *ups* eben nicht "replace" sondern einfach überschreiben mit "$wert = $neuer_wert;"

              Nicht sehr groß heißt für diese Anwendungsart von Arrays in PHP ca. 500kByte bis 1MByte für die Datei.

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

              Tom

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