Niall Atepal: DBM - Willkürliche Zahlen am Ende der Einträge

Hallo

Ich versuche gerade eine kleine DBM-Datenbank zu programmieren.
Funktioniert eigentlich gut. Nur hängt es, wenn ich Dateien aus der Datenbank auslese, willkürlich an jedes Element eine Zahl zwischen 1 und 9 dran und löscht dafür den ersten Buchstaben.
ich kann mir nicht erklären wie das passiert.

Die Variable $nick wird vom vorgehenden Dokument mitgeliefert.

$dbh = dbmopen("./data/$nick", "c")
or die("geht nuescht!");

------------------------------
$name=dbmfetch( $dbh, "name" );
$mail=dbmfetch( $dbh, "mail" );
$passwort=dbmfetch( $dbh, "passwort" );
$alter=dbmfetch( $dbh, "alter" );
$hobby=dbmfetch( $dbh, "hobby" );
$div=dbmfetch( $dbh, "div" );
$uebernachtung=dbmfetch( $dbh, "uebernachtung" );
dbmclose( $dbh );

print "$name<br>";
print "$mail<br>";
print "$alter<br>";
print "$hobby<br>";
print "$div<br>";
------------------------------
Resultat sieht dann irgendwie so aus:

Name: iall Atepal4
Alter: sildur@gmx.ch5
Uebernachtung: oria4
Hobby: ino3
Diverses: a, was soll ich da noch sagen1

Ich freue mich über Tips!

Es grüsst Niall

  1. Halihallo

    was steht dann in der Datei? - Sind dort die Rand-Zahlen auch schon drinne, oder werden sie beim Einlesen "falsch" geholt?
    Zuerst sollte man mal feststellen, wo sich der Fehler befindet. Da ich in deinem Script keinen festgestellt habe, könnte er auch schon in der Datei sein (durch ein falsches Speichern verursacht).
    Zweite Frage: Ist dies bei jedem Datensatz so, oder nur bei einem einzigen?

    Viele Grüsse

    Philipp

    1. Hallo

      Wenn ich die Daten das erstemal auslese sind sie schon falsch. Also muss es wohl irgendwo beim einlesen scheitern. Die Fehler treten bei jedem Datensatz auf.

      So erstelle ich die Datenbank neu, der User muss vorher in nem Formular seinen Nick, den Namen, sein Passwort und ne Mail angeben.

      ----------------------------------
      $dbh = dbmopen("./data/$nick", "c")
      or die("geht nuescht!");

      dbminsert($dbh, "nickname", $nick);
      dbminsert($dbh, "name", $name);
      dbminsert($dbh, "passwort", $pwd);
      dbminsert($dbh, "mail", $mail);
      dbminsert($dbh, "alter", " ");
      dbminsert($dbh, "hobby", " ");
      dbminsert($dbh, "div", " ");
      dbminsert($dbh, "uebernachtung", " ");
      dbminsert($dbh, "bild", "/pics/dummy.jpg");
      dbmclose($dbh);
      ----------------------------------

      Mit folgendem Formular kann man die Daten editieren:
      hier treten die Fehler zum ersten mal auf.

      ---------------------------
      print "<form name="edit" action="update.php>" method="POST">";
      print "Name<br> <input name="name" value="$name" type="text" size="25"><br><br>";
      print "<input name="nick" value="$nick" type="hidden" size="25">";
      print "Mail<br> <input name="mail" value="$mail" type="text" size="25"><br><br>";
      print "Alter<br> <input name="alter" value="$alter" type="text" size="25"><br><br>";
      print "Uebernachtung<br> <input name="uebernachtung" value="$uebernachtung" type="text" size="25"><br><br>";
      print "Hobby<br> <textarea cols="40" rows="6" name="hobby" size="25">$hobby</textarea><br><br>";
      print "Diverses<br> <textarea cols="40" rows="6" name="div" size="25">$div</textarea><br><br>";
      print "<input type="submit" value="Abschicken">";
      ---------------------------

      Grüsse
      Niall

      1. Halihallo

        du benutzt <textarea>'s. D. h. die Returns werden auch mitgeliefert. Eventuell machen genau diese Probleme. Versuch doch einmal mit reg_replace (oder wie der Befehl heisst) alle Returns zu kodieren. Oder noch besser: mach's mit URLescape (kenne den genauen Befehl in php nicht), dann werden alle "komischen/suspekten" - Zeichen kodiert und in eine Linie gepackt. Natürlich musst du diese dann beim Einlesen wieder dekodieren (sonst kriegst du nur Müll).

        Wenn ich die Daten das erstemal auslese sind sie schon falsch.
        Also muss es wohl irgendwo beim einlesen scheitern.

        Diese Folgerung ist nicht korrekt. Was wenn die Daten richtig gelesen werden, aber falsch geschrieben wurden? - Deshalb meine Bitte an dich, dir mal die Datei in einem Editor anzeigen zu lassen.

        Die Fehler treten bei jedem Datensatz auf.

        OK. Dann ist die Kodierung wohl weniger die Ursache für das Problem. Aber: Schau dir die Datei mal an. Sind dort die Daten richtig?

        Viele Grüsse

        Philipp

        1. Halihallo nochmals

          Vielleicht noch ein kleiner Tipp am Rande:

          Da ich mal annehme, dass die build-in Funktionen von php ihren Dienst ordnungsgemäss und richtig machen, folgere ich, dass es irgendwo in deinen Script einen Fehler hat. :-) So weit so gut.

          Also, wo kann der Fehler sein? - Wenn du diese Frage nicht innerhalb von 0.5 Sekunden beantworten kannst, musst du danach suchen. D. h. Woher bekommt das Script die Daten? - Richtig vom CGI - Interface. Also: 1. Scritt: Alle Daten, die vom CGI kommen ausgeben. Dann? - Werden die Daten intern noch geändert? - Wenn ja: ausgeben lassen. 3. Speichern der Daten, 4. Ausgeben der Datei (einfach einlesen und ausgeben lassen), macht der Inhalt der Datei Sinn? - Hat sie die Daten richtig geschluckt, welche du ihr zum Schlucken vorgelegt hast? - Wenn nein: Paradoxon: php hat einen internen Fehler :-)
          Wenn ja, solltest du jetzt irgendwo den Fehler im Output des php-Scripts sehen...

          Sowas nennt man Debugging und hilft dir meistens weiter. Wenn man den Fehler in der Programmierung nicht sieht, muss man eben alles sichtbar machen und Scritt für Schritt überprüfen, was denn das Script tut.

          Viele Grüsse

          Philipp

        2. Hallo

          AH.. Jetzt begreife ich, was du gemeint hast.
          Also, wenn ich die Dateien mit nem Editor anschaue, dann sind sie wenn ich sie ganz frisch eingetragen habe noch normal.
          Wenn ich die Daten editiert habe, verdoppelt sich der Inhalt der DB. d.h. der neue Inhalt wird einfach unter den alten geschrieben. Beim alten sind nun die ersten Buchstaben von allen Einträgen gelöscht.
          Die Zahlen dahinter sind bei jedem Eintrag vorhanden.

          Interessanterweise wird zwar der neue Eintrag abgerufen, wenn ich die Dateien erneut auslese, aber die ersten Buchstaben sind jetzt auch dort abgeschnitten. Ich begreife immer weniger...

          Grüsse
          Niall

          1. Halihallo Niall

            AH.. Jetzt begreife ich, was du gemeint hast.

            Oh, entschuldige, wenn ich mich nicht verständlich ausgedrückt habe.

            Also, wenn ich die Dateien mit nem Editor anschaue, dann sind sie wenn ich sie ganz frisch eingetragen habe noch normal.

            So weit so gut.

            Wenn ich die Daten editiert habe, verdoppelt sich der Inhalt der DB. d.h. der neue Inhalt wird einfach unter den alten geschrieben. Beim alten sind nun die ersten Buchstaben von allen Einträgen gelöscht.

            Was??? - Also entweder haben wir einen Bug von php entdeckt, was ich nicht glaube, oder dein editier - Script macht was falsch. Auf jeden Fall haben wir den Fehler auf das Editier-Script beschränkt. Es hängt definitiv nicht an deinem Script, welches du gepostet hast (Ausgabe der Form für den Update).

            Interessanterweise wird zwar der neue Eintrag abgerufen, wenn ich die Dateien erneut auslese, aber die ersten Buchstaben sind jetzt auch dort abgeschnitten. Ich begreife immer weniger...

            Ich ehrlich gesagt auch :-((
            Am Besten, du postest mal den Code für das Update - Script. Da sich dort der Fehler befindet.

            Viele Grüsse

            Philipp

            1. Heyoh

              Ich ehrlich gesagt auch :-((
              Am Besten, du postest mal den Code für das Update - Script. Da sich dort der Fehler befindet.

              Der Fehler muss sich nicht (nur) im Update-Script befinden, da der Fehler schon auftauch, bevor ich die Daten das erstemal editiere. Der Fehler taucht schon beim erstenmal abrufen der Daten auf. Ich hab das Gefühl, dass der eine Fehler eben beim Abruf passiert, der zweite, wenn ich die DB update.
              Nun, ich gehe jetzt nochmals Schritt für Schritt meine Scripts durch und Prüfe wo nun wirklich genau Fehler auftauchen.
              Ich danke schon mal für die Hilfe!
              Ich melde mich wieder, sobald ich mehr weiss

              Grüsse
              Niall

              1. Hallo

                Ich habe jetzt mal eine ganz simple Datenbank generiert, es werden zwei Werte in eine Datenbank eingetragen und mit einem weitern Script wieder aus der DB ausgelsen. Die Fehler treten immer noch auf. Das Problem muss jetzt fast an meinem Server oder tatsächlich beim PHP liegen.
                Ich poste trotzdem nochmals meine neuen Scripte:

                -----------eintragen.php-----------------------------------
                <?php
                $nick = "Anina";
                $pwd = "sugus";

                $dbh = dbmopen("./data/test", "c")
                       or die ("neeeeeeeeeeeeeeeeee");
                dbminsert($dbh, $nick, $pwd);
                dbmclose($dbh);
                ?>
                -----------------------------------------------------------
                ----------auslesen.php-------------------------------------
                <?php
                $dbh = dbmopen("./data/test", "c")
                       or die ("neeeeeeeeeeeeeeeeee");
                $pass= dbmfetch($dbh, "Anina");
                dbmclose($dbh);
                print "$pass";
                ?>
                -----------------------------------------------------------

                Das Resultat ist: ugusa
                Wenn ich die Tabelle in einem Editor öffne sehe ich folgendes:
                5
                Anina5
                sugus

                Ist schon unmöglich... ich glaube ich suche mir eine andere Lösung.
                DBM Wäre einfach sehr praktisch gewesen, da ich nicht wirklich zuviel Geld habe, um mir einen MySQL bei meinem Provider zu leisten :(
                Oder kennt jemand von euch eine ebenso günstige DB Version?

                Niall

                1. Halihallo

                  Ich habe jetzt mal eine ganz simple Datenbank generiert, es werden zwei Werte in eine Datenbank eingetragen und mit einem weitern Script wieder aus der DB ausgelsen. Die Fehler treten immer noch auf. Das Problem muss jetzt fast an meinem Server oder tatsächlich beim PHP liegen.

                  [...]

                  Spok würde sagen: "Faszinierend!". Ich hab echt keine Ahnung, wie dieser Output von php zu stande kommt. Dein Script ist ja voll IO, meiner bescheidenen php-Erfahrung nach... Was zum h... macht php hier??? - Da sollte vielleicht mal ein php-Expert ran...

                  Ist schon unmöglich... ich glaube ich suche mir eine andere Lösung.

                  1. Einfaches Testscript machen (hast du ja bereits), wenn das fehlschlägt
                  2. Dokumentation zu den Befehlen lesen. Ist dir Output dann "gerechtfertigt"? - Wenn nein
                  3. andere Lösung suchen...

                  Insofert würde ich an deiner Stelle gleich entscheiden...

                  DBM Wäre einfach sehr praktisch gewesen, da ich nicht wirklich zuviel Geld habe, um mir einen MySQL bei meinem Provider zu leisten :(
                  Oder kennt jemand von euch eine ebenso günstige DB Version?

                  Ja, selberprogrammieren. Die DBM-Funktion ist ja nun wirklich nicht sehr schwer. Folgendes Schema:

                  Datei öffnen;
                  while (!EOF) {
                     linie lesen;
                     nach dem ersten '=' aufsplitten => Array($key_name, $key_value);
                     in einem assoziativen Array speichern (auch als Hash bekannt)
                  }
                  Datei schliessen;
                  assoz. Array zurückgeben oder einen bestimmten Wert daraus.

                  Viele Grüsse

                  Philipp

      2. Hallo

        Moin Moin!


        $dbh = dbmopen("./data/$nick", "c")
        dbminsert($dbh, "nickname", $nick);

        [...]

        dbmclose($dbh);

        Mit folgendem Formular kann man die Daten editieren:
        hier treten die Fehler zum ersten mal auf.


        [...]

        print "<input name="nick" value="$nick" type="hidden" size="25">";

        [...]

        Wenn sich nicht ganz auf dem Schlauch stehe, erlaubst Du dem User, seinen Nickname selbst festzulegen (ist ja auch wohl üblich so). Den Nickname in $nick benutzt Du dann ungeprüft, um eine Datei im Dateisystem zu öffnen.

        *** RED ALERT! INTRUDER DETECTED! ***

        Ich weiß nicht genau, wie dbmopen reagiert, wenn es Zeichen wie `` | > < ; * ? \ <NUL> im Dateinamen findet. Wenn die darunterliegende C-Funktion nur ein fopen() macht, ist das OK. Wenn nicht, hast Du ein Problem. Überleg mal, was passiert, wenn ich als Nickname folgendes eingebe:

        ../../../../../../../../../../../etc/passwd

        oder für Windows 95/98:

        ../../../../../../../../../../../io.sys

        oder für Windows NT/2000:

        ../../../../../../../../../../../ntldr

        Zweite Sache: Wenn $nick einen User eindeutig kennzeichnet, warum schreibst Du $nick in eine "Datenbank", die extra für $nick angelegt wurde ? Wolltest Du nicht alle Nicknames in eine Datei schreiben ?

        Alexander

        1. Heyoh Alexander

          Das Problem mit dem ungeprüften Nick seh ich schon. Das werde ich noch einbauen, aber zuerst wollte ich die restlichen Scripts lauffähig bringen und dann die Sicherheitselemente dazufügen.
          Ich baue Scripts immer so auf, dass zuerst nur die Grundelement laufen und ergänze dann alles immer mehr.

          Zweite Sache: Wenn $nick einen User eindeutig kennzeichnet, warum schreibst Du $nick in eine "Datenbank", die extra für $nick angelegt wurde ? Wolltest Du nicht alle Nicknames in eine Datei schreiben ?

          Das ist auch noch nicht ganz definitiv. ich habe sonst auch eine Datenbank, in welcher alle Nicks deponiert sind.

          Grüsse
          Niall