Dev: Newbie braucht Hilfe !!!

Hi Leute,

Ich bin noch ein relativer Newbie was php betrifft, also nicht böse sein falls die Frage schon mal kam (hab allerdings nicht finden können). ;)
Es geht um folgendes. Ich habe eine txt Datei mit Adressdaten, diese möchte ich ändern bzw. löschen können.
Hab zu dem Thema was bei http://www.koehntopp.de/ gefunden, aber leider funktiniert das nicht so wie ichs mir vorstelle.Die Daten werden zum Ändern aufgerufen und auch neu geschrieben, das geht aber alles nur EINMAL. Danach wird eine ganz andere Zeile gelöscht und die zu ändernde wird immer hin ran gehangen.

if ($submit) {
$str="$ID|$login|$pwd|$firma|$name|$vorname|$strasse|$plz|$ort| \n";
echo "<b>$ID1, <br> $str<br></b>";
$datei = "kunden.txt";
$dat="funzt.txt";
$fp = fopen($datei,"r");
flock($fp, 1) or die("Kann die Quelldatei $datei nicht locken.");
$fp1 = fopen($dat,"w");
flock($fp1, 2) or die("Kann die Zieldatei $dat nicht locken.");
$no = "0";
while($line = fgets($fp, 1000)){
  if (++$no == $ID1)
    continue;
fputs($fp1, $line);
 }
 fclose($fp);
 fclose($fp1);

$fp2=fopen("$dat","a+");
fputs($fp2, $str);
fclose($fp2);
copy("funzt.txt", "user.txt");
}

Gibt es eine Möglichkeit an der Stelle
  if (++$no == $ID1) zu stoppen und den geänderten Datensatz einzutragen und dann dann halt den Rest bezubehalten?

Ich bin für jede Hilfe dank bar.
Gruesse Dev

  1. Es geht um folgendes. Ich habe eine txt Datei mit Adressdaten, diese möchte ich ändern bzw. löschen können.
    Hab zu dem Thema was bei http://www.koehntopp.de/ gefunden, aber leider funktiniert das nicht so wie ichs mir vorstelle.Die Daten werden zum Ändern aufgerufen und auch neu geschrieben, das geht aber alles nur EINMAL. Danach wird eine ganz andere Zeile gelöscht und die zu ändernde wird immer hin ran gehangen.

    Du hast da ein konzeptionelles Problem: Du vergleichst nicht die Nummer eines Datensatzes (die du ja mit $ID am Anfang jeder Zeile stehen hast), sondern die Zeilennummer aus deinem Zähler $no.
    Sowas kann leicht in's Auge gehen, insbesondere, wenn man dann den geänderten Datensatz an's Ende anhängt, anstatt ihn wieder in die Zeile zu schreiben, in der er ursprünglich mal war.

    Ausgangsdatei:

    Zeile  Daten
    1      1 Ernie
    2      2 Bert
    3      3 Grobi
    4      4 Krümelmonster

    Wenn du jetzt Eintrag 2 änderst, bekommst du:

    Zeile  Daten
    1      1 Ernie
    2      3 Grobi
    3      4 Krümelmonster
    4      2 Bert

    Dein Datensatz 2 (Bert) ist also in die letzte Zeile gerutscht. Wenn du jetzt nochmal durchläufst, erwischt du statt Datensatz 2 (Bert) Zeile 2, an der jetzt Datensatz 3 (Grobi) steht.

    Lösung: Lies aus jeder Zeile die Nummer des Datensatzes aus und vergleiche die. Oder ersetze dein "continue;" in der Schleife durch "$line=$str;", um an die Position der alten Datenzeile die geänderte zu schreiben.
    Da du jetzt schon über den Fehler, sich auf Umwege zu verlassen, gestolpert bist, würde ich dir ersteres empfehlen.

    Gruß,
      soenk.e

    PS: Dateien sind tote Objekte, die kann man nicht locken ;)

    1. Hi soenk.e
      "$line=$str;", --> genau das  suche ich schon die ganze Zeit

      Danke !!! :)

      Ein Problem bleibt trotzdem noch, wie ersetzte ich die gelösche Zeile?

      Denn wenn ich Eintrag 2 lösche rückt, doch ebenfalls Eintrag 3 auf die Position 2.

      Gruss Dev

      1. "$line=$str;", --> genau das  suche ich schon die ganze Zeit

        Danke !!! :)

        Ein Problem bleibt trotzdem noch, wie ersetzte ich die gelösche Zeile?

        Das hast du doch gerade eben mit obiger Zeile getan :) In $line steht doch das, was du aus der alten Datei gelesen hast, in $str befindet sich die neue, geänderte Datenzeile. Mit $line=$str ersetzt du also den alten Inhalt durch den neuen, und anschließend wird $line in die neue Datei geschrieben.

        Du mußt dann allerdings das Ende deines Skripts entfernen, also dort, wo du die neuen Daten an die neue Datei anhängst, andernfalls hast du die neue Zeile doppelt.

        Denn wenn ich Eintrag 2 lösche rückt, doch ebenfalls Eintrag 3 auf die Position 2.

        Nein. Gehe dein Skript doch nochmal in aller Ruhe durch und überleg' dir genau, was jede einzelne Zeile macht.

        Ich würde dir aber trotzdem raten, die Datensätze anhand der ID zu identifizieren als anhand der Zeilennummer.

        Gruß,
          soenk.e

  2. Was prinzipielles:

    du kannst bei datein nur folgendes machen:

    Lesen, Anhängend schreiben, löschen.

    willst du also was ändern musst du die gesamte datei neu schreiben.
    (das geht auch ohne das du ne neue datei dafür verwendest und dann nur kopierst.

    ich schreib mal mehr oder weniger pseudo code um die die funktin zu verdeutlichen:

    myfile enthält zb.
    1;max muustermann;musterstrasse;musterstadt
    2;foo;bar;foobar

    jetzt wollte ein user den eintrag foo;bar;foobar ändern,

    $cid=2; // id die geändert gehört

    $adressen=file("myfile.csv");
    for($i=0;$i<count($adressen);$i++){
        $ad_array=explode(";",$adressen[$i]);
        if($ad_array[0]==$cid){
          $ad_array[1]="neuer name";
          $ad_array[2]="neue strasse";
          $ad_array[3]="neuer ort";
        }
        $newfile[]=$ad_array;
    }

    $f=fopen("myfile.csv");
    for($i=0;$i<count($newfile);$i++){
       fputs($f,$newfile[$i]."\n");
    }
    fclose($f);

    ---------------

    Man bräuchte die 2te schleife nicht unbedingt, man könnte auch eine neue var gleich mit den werten füllen und gleich schreiben, aber ich denke es ist so mal übersichtlicher.

    lg
    Ludwig

    1. Hallo Ludwig,

      (das geht auch ohne das du ne neue datei dafür verwendest und dann nur kopierst.

      ich habe das schon versucht gehabt mit einer Datei, habe aber immer nur den letzten Datensatz erhalten und auch der Suche nach Hilfe bin ich auf das Script gestoßen.

      Ich habe es von Datei löschen und umbennen, auf copy geändert, weil ich ansonsten ständig die Rechte ändern mußte.

      Aber ich danke für die Hilfe!!!
      Gruss Dev