Sp33dy G0nz4l3s: Problem beim Anzeigen von Fehlermeldungen

Hi, wie ich schon in einem anderen Thread geschrieben habe, erstelle ich zur Zeit ein Kontaktformular für meine Seite:

http://www.cs-erweiterungen.de/scripts/viewcomments.php

Nun habe ich eine Funktion erstellt, mit der geprüft wird ob alles eingegeben wurde. Diese Funktion steht ganz oben im Script. Hier ein Ausschnitt:

if (isset($_POST['submit']) && !$unique) {
 $fehler = false;
 $fehlertext ="";

if (empty($_POST["Name"])) {
  $fehler = true;
  $fehlertext .= "Bitte gib einen Namen ein.<br>\n";
 }

elseif (strlen($_POST['Name']) < 4) {
  $fehler = true;
  $fehlertext .= "Der Name muss mehr als 3 Buchstaben haben.<br>\n";
  }

$muster = "/[1]+@[a-zA-Z0-9-_.]+.[a-zA-Z]{2,4}$/";
  if (preg_match($muster, $_POST['Email']) == 0 && !empty($_POST["Email"])) {
     $fehler = true;
     $fehlertext .= "Die angegebene E-Mail-Adresse ist ungültig!<br>\n";
  }
}

Weiter unten möchte ich dann einen Text ausgeben, in dem dann die Fehlermeldungen stehen. Das will ich dann so machen:

if ($fehler) {
  echo "<p>".$fehlertext."</p>";
 }

Wenn ich diesen Code oben nach dem letzen Code einfüge funktioniert es perfekt. Ich will jedoch das es weiter unten erst angezeigt wird. Nun habe ich folgendes Problem. Bei "Bitte gib einen Namen ein." wird es unten angezeigt. Bei "Der Name muss mehr..." & "Die angegebene E-Mail-Adresse..." wird es nur angezeigt, wenn  auch die Fehlermeldung von dem Namen kommt.

Ich hoffe ihr versteht was ich meine. Ihr könnt es auch bei dem Script testen:
http://www.cs-erweiterungen.de/scripts/viewcomments.php

Das komplette Script habe ich hier einmal hochgeladen:
http://www.cs-erweiterungen.de/files/SCRIPT.txt


  1. a-zA-Z0-9-_. ↩︎

  1. »»Bei "Bitte gib einen Namen ein." wird es unten angezeigt. Bei "Der »»Name muss mehr..." & "Die angegebene E-Mail-Adresse..." wird es nur »»angezeigt, wenn  auch die Fehlermeldung von dem Namen kommt.

    Muss mich noch mal verbessern es wird nur ein Fehler angezeigt, wenn etwas bei Kommentar steht. Das kommt nach der Prüfung der E-Mail. Hatte ich weggelassen damit es nicht zu viele Zeichen werden.

    Hier könnt ihr es euch komplett anschauen:
    http://www.cs-erweiterungen.de/files/SCRIPT.txt

    1. »»Bei "Bitte gib einen Namen ein." wird es unten angezeigt. Bei "Der »»Name muss mehr..." & "Die angegebene E-Mail-Adresse..." wird es nur »»angezeigt, wenn  auch die Fehlermeldung von dem Namen kommt.

      Muss mich noch mal verbessern es wird nur ein Fehler angezeigt, wenn etwas bei Kommentar steht. Das kommt nach der Prüfung der E-Mail. Hatte ich weggelassen damit es nicht zu viele Zeichen werden.

      Hier könnt ihr es euch komplett anschauen:
      http://www.cs-erweiterungen.de/files/SCRIPT.txt

      Habe es hinbekommen :)

      Es glaube ich daran, das $fehler = true; nach ?> "gelöscht" wurde. Bzw nur der letzte Wert erhalten blieb.

  2. Hi!

    OK. Dein Problem hast du ja mittlerweile ganz alleine gelöst.
    Ich hätte allerdings noch ein paar kleine Verbesserungsvorschläge.

    elseif (strlen($_POST['Name']) < 4) {
      $fehler = true;
      $fehlertext .= "Der Name muss mehr als 3 Buchstaben haben.<br>\n";
      }

    Was ist denn mit den Leuten, die einen kürzeren Namen haben?
    Kommt sicher nicht so oft vor, gibt es aber.
    Eine griechische Freundin von mir heißt beispielsweise "Jo".

    $muster = "/[1]+@[a-zA-Z0-9-_.]+.[a-zA-Z]{2,4}$/";

    Das sieht nicht so aus, als ob du wirklich alles bedacht hättest...
    ".....mail.....adresse.....@.....provider.....de" wäre nach deinem RegEx wohl eine gültige Adresse, wie mir scheint.
    Am Anfang der Mailadresse darf beispielsweise kein Punkt stehen.

    Du kannst gerne den RegEx benutzen, den ich mir mal für meine Email-Validitäsprüfungsfunktion zusammengebastelt habe.
    $expression = "[2](.{0,1}[_a-zA-Z0-9-])*@([a-zA-Z0-9-]{2,}.){0,}[a-zA-Z0-9-]{3,}(.[a-zA-Z]{2,4}){1,2}$";
    Genaugenommen ist mein RegEx allerdings auch nicht wirklich korrekt.
    Maildressen dürfen im ersten Teil (vor dem @) nämlich eigentlich auch noch andere Zeichen wie {}~|#!$%*&'-+/?^=` enthalten.
    Dann gibt es noch bestimmte Vorschriften für die Länge von Mailadressen, die ich auch nicht berücksichtigt habe und ein paar andere Dinge.
    Mittlerweile dürfen Mailadressen (seit der Einführung der neuen Umlaut-Domains) auch Umlaute enthalten (im Domain-Teil), die allerdings mit Punycode in einen ACE-String (ASCII Compatible Encoding) übertragen werden.
    Ich schätze mit meinem RegEx funktioniert das. Ganz sicher bin ich mir aber nicht.
    Muß mir das mit der Punycode-Vorschrift noch mal genau anschauen...
    Ich wollte mir eigentlich mal die entsprechenden RFCs raussuchen und einen RegEx basteln, der wirklich alles beeinhaltet.
    Nur irgendwie bin ich niemals dazu gekommen, weil ich genau weiß, daß das einige Zeit dauern wird, bis ich diesen RegEx zusammengebastelt habe.
    Vielleicht setze ich mich da aber die nächsten Tage mal dran...

    So, jetzt aber wieder zu deinem Code.
    Deine Prüfungen sind nicht ausreichend und sogar verdammt gefährlich.
    Du übernimmst die Werte, quasi ungeprüft, und schreibst sie in deine Datenbank.
    Du hast hier ein Sicherheitsloch weit aufgerissen.
    Dein Code ermöglicht einen Angriff per SQL-Injection auf deine Datenbank.
    Such mal (z.B. in der Wikipedia) nach "SQL-Injection".

    $sql = "INSERT INTO kommentare " .

    "VALUES ('', '$_POST[Name]', '$_POST[Homepage]', '$_POST[Email]', " .
      "'$datum', '$_POST[Kommentar]', '$_POST[Page]')";
    Was ist jetzt, wenn jemand SQL-Code in einem Feld eingibt?
    Den mußt du in jedem Fall unschädlich machen bzw. rausfiltern. Du willst doch nicht, daß dir vielleicht jemand die Datenbank killt, oder?
    Filter SQL-Code raus, escape bestimmte Sonderzeichen, usw..
    Schau dir am besten mal die Funktion mysql_real_escape_string() an.

    mysql_query($sql);

    Hier setzt du keinerlei Fehlerbehandlung ein.
    Ich würde hier wohl die Ausgabe einer etwaigen Fehlermeldung mit einem vorangestellten @ unterdrücken und dann dem User eine Meldung wie: "Leider trat ein Fehler auf, blablabla" zeigen.

    Außerdem sind die Variablennamen fehlerhaft.
    Statt $_POST[Name] meinst du $_POST['Name']. Du nutzt hier also eine nicht definierte Konstante.
    Je nachdem, wie das Error-Reporting auf dem Server eingestellt ist, könntest du recht unschöne und nervige Ausgaben erhalten.
    Wenn das passiert, funktioniert der spätere Aufruf von header() nicht mehr und deine Umleitung funktioniert nicht.

    @mail("marc-metz@web.de", "Es gibt ein neues Kommentar", "$mailbody", "From: $email");

    Auch nicht schön. Da fehlen zusätzliche Header.
    Du solltest zumindest festlegen, welche Zeichencodierung zum Einsatz kommt. Du möchtest doch, daß Sonderzeichen wie Umlaute korrekt angezeigt werden?
    Ich würde sowas hier einsetzen:
    $headers = "From: $_POST['Email']\r\n";
    $headers.= "Reply-To: $_POST['Email']\r\n";
    $headers.= "MIME-Version: 1.0\r\n";
    $headers.= "Content-type: text/plain; charset=UTF-8\r\n";
    $headers.= "X-Mailer: PHP/" . phpversion();

    $datum = date("d.m.Y, H:i") . " Uhr";

    Warum machst du das so? Wäre es nicht viel sinnvoller, eines der MySQL-Zeitfelder zu nutzen? Dann könntest du auch die SQL-Zeitfunktionen einsetzen.
    Oder du machst auf dem Feld ein INT-Feld und schreibst das Datum in Form eines UNIX-Timestamps in die Datenbank.
    Das erleichtert dir die Weiterverarbeitung ungemein.
    Damit könntest du dann später viel mehr anstellen und die Ausgabemöglichkeiten sind viel flexibler.
    Du könntest dir dann z.B. auch den Wochentag ausgeben lassen oder du hättest dann die Möglichkeit, Ausgaben zeitlich sortiert zu machen.

    Header("Location: ".$_POST['Redirect']);

    Auch ein Fehler.
    Ich weiß nicht, wieso du hier den Wert aus einem Hidden-Feld im Formular übergibst und diesen dann nutzt.
    Wieso nicht den URL direkt der Header-Funktion übergeben? Nunja, aber jedenfalls ist der Inhalt der Variablen hier "viewcomments.php".
    Die Funktion header() erwartet allerdings einen vollständigen URL (mit http://).
    (Ja, ich weiß: es funktioniert bei dir auch so. Ist aber trotzdem falsch.)

    So. Ich glaube, das war es erstmal...
    Ansonsten würde ich allerdings zusätzlich noch Javascript für eine clientseitige Überprüfung der Formulareingaben nutzen.
    Allerdings nicht so, daß die Seite nicht mehr ohne JS nutzbar ist - halt nur zusätzlich.
    So könntest du mittels JS dann vielleicht Einblendungen machen, wenn ein Feld nicht korrekt ausgefüllt wurde.
    Dazu würde ich allerdings nicht mit nervigen Alert-Boxen kommen, sondern ich würde Texte neben den entsprechenden Formularfeldern einblenden.

    Schöner Gruß,
    rob


    1. a-zA-Z0-9-_. ↩︎

    2. _a-zA-Z0-9- ↩︎