Philip: Werte in MySQL-DB schreiben nur umständlich möglich

Hi,

ich kenn mich nicht besonders gut mit PHP in Verbindung mit MySQL aus, und wollte nun eine Tabelle anlegen, über die ich mit einem Formular Werte eintragen kann.

Tabelle ist korrekt angelegt, Formular ist erstellt, nur klappt das mit dem Eintragen nicht so ganz.

Ich habe also diverse Eingabefelder

Hersteller: <input type="text" name"hersteller"><br>  
Bezeichnung: <input type="text" name"bezeichnung"><br>  
Kapazitaet: <input type="text" name"kapazitaet">

Laut einem Buch (PHP lernen) übergebe ich die Werte nun wie folgt an die Tabelle:

$eintrag = "INSERT INTO usb (hersteller, bezeichnung, kapazitaet) VALUES ('$hersteller', '$bezeichnung', '$kapazitaet')";  
$eintragen = mysql_query($eintrag);

Wenn ich das Formular abschicke kommt kein Fehler, in der Tabelle wird zwar korrekt ein Datensatz angelegt, aber alle Felder sind leer.

Da ich mir früher mal ein kleines CMS gebastelt habe wo ich schon mit Formularen und MySQL gearbeitet habe, habe ich geschaut, wie ich das dort gemacht hatte. Dort sieht der PHP-Code für den MySQL-Teil so aus:

  $hersteller = $_POST['hersteller'];  
  $bezeichnung = $_POST['bezeichnung'];  
  $kapazitaet = $_POST['kapazitaet'];  
  
  $eintrag = sprintf("INSERT INTO usb (hersteller,bezeichnung,kapazitaet) VALUES ('%s', '%s', '%s')", mysql_real_escape_string($hersteller), mysql_real_escape_string($bezeichnung), mysql_real_escape_string($kapazitaet));  
  $eintragen = mysql_query($eintrag);

Keine Ahnung wie ich damals darauf gekommen bin, ich hatte damals das gleiche Buch wie heute :D
Jedenfalls klappt es damit.

Kann mir jemand verraten, was an Variante 1 falsch ist bzw. wieso ich das über den für mich komplizierteren Weg 2 gehen muss?

Danke

  1. Hersteller: <input type="text" name"hersteller"><br>

    Bezeichnung: <input type="text" name"bezeichnung"><br>
    Kapazitaet: <input type="text" name"kapazitaet">

      
    
    > Wenn ich das Formular abschicke kommt kein Fehler, in der Tabelle wird zwar korrekt ein Datensatz angelegt, aber alle Felder sind leer.  
      
    sieh dir bitte die 3 von dir geposteten zeilen noch genau an (attribut für attribut), du solltest den fehler schnell finden  
    
    
    1. sieh dir bitte die 3 von dir geposteten zeilen noch genau an (attribut für attribut), du solltest den fehler schnell finden

      Hoppla, da hab ich mich hier nur vertippt.

      Daran liegts aber leider nicht :(

      1. Hi!

        Daran liegts aber leider nicht :(

        Es liegt wohl an: register_globals=off

        off:PP

        --
        "You know that place between sleep and awake, the place where you can still remember dreaming?" (Tinkerbell)
        1. Es liegt wohl an: register_globals=off

          off:PP

          Dann ist als die "komplizierte" Variante so korrekt?

          1. Dann ist als die "komplizierte" Variante so korrekt?

            bzw. die richtige Lösung (korrekt ist's ja, weil es so  geht :))

            1. bzw. die richtige Lösung (korrekt ist's ja, weil es so  geht :))

              es sind beide lösungen (abhängig von der servereinstellung) korrekt

              sicherer ist, sich nicht auf register_globals zu verlassen - zudem fällt ab php 6 register_globals komplett raus ;)

              1. Gut, hab ich grad auf php.net gelesen :)

                Vielen Dank für die schnelle Hilfe!

                Dann hät ich aber gleich noch eine kurze Frage bzgl. Dezimalzahlen.

                Wenn ich in der Tabelle eine Dezimalzahl (z.B. 110,99 bzw. 110.99) eintragen möchte, ist dann ein Feld vom Typ decimal(3,2) korrekt?

                1. echo $begrüßung;

                  Wenn ich in der Tabelle eine Dezimalzahl (z.B. 110,99 bzw. 110.99) eintragen möchte, ist dann ein Feld vom Typ decimal(3,2) korrekt?

                  Nein, denn 3 ist die Gesamt-Länge inklusive Nachkommastellen. 5 wäre in deinem Fall passender. Außerdem musst du das Komma beachten, wenn das jemand eingegeben hat, und in einen Punkt umwandeln.

                  echo "$verabschiedung $name";

                  1. Alles klar, vielen Dank!

                2. Wenn ich in der Tabelle eine Dezimalzahl (z.B. 110,99 bzw. 110.99) eintragen möchte, ist dann ein Feld vom Typ decimal(3,2) korrekt?

                  sollte eigentlich 5,2 sein
                  http://dev.mysql.com/doc/refman/5.1/de/precision-math-decimal-changes.html

                  der erste wert gibt die anzahl der stellen an, der zweite gibt an, wieviele davon rechts vom komma stehen

  2. Hello,

    Keine Ahnung wie ich damals darauf gekommen bin, ich hatte damals das gleiche Buch wie heute :D

    Na ja, zur damaligen Zeit war wahrscheinlich register_globals aktiv.

    MfG
    Rouven

    --
    -------------------
    sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
    Konsens ist kein Beweis  --  John Naisbitt
  3. Hello,

    schalte zum Entwickeln immer das Errorporting auf mindestens 2047
    also ein

    error_reporting(E_ALL);

    am Anfang des Scriptes würde das bewirken oder auf einem Apachen ein Eintrag in einer .htaccess

    php_value error_reporting 2047

    Dann solltest Du sehen, ob es die Variablen in Deinem SQL-Satetement überhaupt gibt.
    Außerdem empfiehlt es sich zum Debuggen auch, das SQL-Statement ausgeben zu lassen

    $eintrag = "INSERT INTO usb (hersteller, bezeichnung, kapazitaet) VALUES ('$hersteller', '$bezeichnung', '$kapazitaet')";
      echo htmlspecialchars($eintrag);

    Liebe Grüße aus Syburg bei Dortmund

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Ah das ist gut, da bekomm ich entsprechende Meldungen

      Notice: Undefined variable: hersteller .. on line 7

      etc.

      1. Hello,

        Ah das ist gut, da bekomm ich entsprechende Meldungen

        Notice: Undefined variable: hersteller .. on line 7

        Und das sollte Dich daran erinnern, das Post-Paramter schon lange als Elemente im $_POST-Array landen.
        Deinen "hersteller" findest Du also dann in $_POST['hersteller'] wieder.

        siehe hierzu auch http://de2.php.net/manual/en/language.variables.predefined.php
        und http://de2.php.net/manual/en/reserved.variables.php

        Liebe Grüße aus Syburg bei Dortmund

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
  4. echo $begrüßung;

    $hersteller = $_POST['hersteller'];

    $bezeichnung = $_POST['bezeichnung'];
      $kapazitaet = $_POST['kapazitaet'];

    $eintrag = sprintf("INSERT INTO usb (hersteller,bezeichnung,kapazitaet) VALUES ('%s', '%s', '%s')", mysql_real_escape_string($hersteller), mysql_real_escape_string($bezeichnung), mysql_real_escape_string($kapazitaet));
      $eintragen = mysql_query($eintrag);

      
    
    > Kann mir jemand verraten, was an Variante 1 falsch ist bzw. wieso ich das über den für mich komplizierteren Weg 2 gehen muss?  
      
    Variante 1 funktioniert nur mit dem veralteten PHP-Feature [Register Globals](http://www.php.net/manual/en/security.globals.php). Außerdem ist sie falsch, weil sie den Kontext "SQL-Statement" nicht berücksichtigt. Du übergibst die Werte ohne weitere Behandlung, was bestenfalls einen Syntaxfehler ergibt, wenn darin ein ' vorkommt. In weniger günstigen Fällen kann man mittels [SQL-Injection](http://www.php.net/manual/en/security.database.sql-injection.php) noch mehr anstellen. Um SQL-Injection zu vermeiden kennt PHP ein weiteres und ebenfalls veraltetes Feature namens [Magic Quotes](http://www.php.net/manual/en/security.magicquotes.php). Da du in Variante 2 mit mysql\_real\_escape\_string() selbst dafür sorgst, dass die Werte kontextgerecht behandelt werden, musst du auch dafür sorgen, dass die [Magic Quotes deaktiviert](http://www.php.net/manual/en/security.magicquotes.disabling.php) sind. Für Variante 2 ist es übrigens nicht notwendig, die Werte im $\_POST-Array nochmal in andere Variablen umzukopieren. Du kannst genauso gut $\_POST['hersteller'] an den Stellen verwenden, an denen du $hersteller verwendet hat. Bis auf das Umkopieren ist Variante 2 das Minimum, auch sicherheitstechnisch betrachtet. Sehr schön ist auch die Verwendung von sprintf(), das macht das SQL-Statement lesbarer als bei direkter Stringverknüpfung.  
      
      
    echo "$verabschiedung $name";