Gustav Gans: Frage zum 'E-Mail-Kontrolle'-Artikel von Christian Kruse

Moin!

Ich beziehe meine Frage auf den Artikel E-Mail-Kontrolle von Christian Kruse, erschienen auf SELFHTML.

Ich habe den dortigen Code 1:1 übernommen, um eine in einem Formular eingegebene Mailadresse ($_POST['mail'])zu überprüfen.

Wenn ich die Variable übernehme und umschreibe (was man ja laut vielen Expertenpostings hier NICHT tun soll, ich wandle also das $_POST['mail'] um in $email, dann schaut es so aus UND funktioniert:

 if((empty($_POST['mail'])==true))  
  {  
   $mailerror="Die Mailadresse <strong>muß</strong> angegeben werden.";  
   $checkmail=false;  
  }  
 else  
  {  
   $email=$_POST['mail'];  
   function check_email($email)  
    {  
     $nonascii      = "\x80-\xff";  
     $nqtext        = "[^\\\\$nonascii\015\012\"]";  
     $qchar         = "\\\\[^$nonascii]";  
     $protocol      = '(?:mailto:)';  
     $normuser      = '[a-zA-Z0-9][a-zA-Z0-9_.-]*';  
     $quotedstring  = "\"(?:$nqtext|$qchar)+\"";  
     $user_part     = "(?:$normuser|$quotedstring)";  
     $dom_mainpart  = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.';  
     $dom_subpart   = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*';  
     $dom_tldpart   = '[a-zA-Z]{2,5}';  
     $domain_part   = "$dom_subpart$dom_mainpart$dom_tldpart";  
     $regex         = "$protocol?$user_part\@$domain_part";  
     return preg_match("/^$regex$/",$email);  
    }  
   if(check_email($email))  
    {  
     $checkmail=true;  
    }  
   else  
    {  
     $mailerror="Die angegebene Mailadresse scheint <strong>ungültig</strong> zu sein.";  
     $checkmail=false;  
    }  
  }

Wenn ich die Variable aber NICHT umschreibe und das $_POST['mail'] DIREKT verwende, wenn ich es also SO mache =>

 if((empty($_POST['mail'])==true))  
  {  
   $mailerror="Die Mailadresse <strong>muß</strong> angegeben werden.";  
   $checkmail=false;  
  }  
 else  
  {  
   function check_email($_POST['mail'])  
    {  
     $nonascii      = "\x80-\xff";  
     $nqtext        = "[^\\\\$nonascii\015\012\"]";  
     $qchar         = "\\\\[^$nonascii]";  
     $protocol      = '(?:mailto:)';  
     $normuser      = '[a-zA-Z0-9][a-zA-Z0-9_.-]*';  
     $quotedstring  = "\"(?:$nqtext|$qchar)+\"";  
     $user_part     = "(?:$normuser|$quotedstring)";  
     $dom_mainpart  = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.';  
     $dom_subpart   = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*';  
     $dom_tldpart   = '[a-zA-Z]{2,5}';  
     $domain_part   = "$dom_subpart$dom_mainpart$dom_tldpart";  
     $regex         = "$protocol?$user_part\@$domain_part";  
     return preg_match("/^$regex$/",$_POST['mail']);  
    }  
   if(check_email($_POST['mail']))  
    {  
     $checkmail=true;  
    }  
   else  
    {  
     $mailerror="Die angegebene Mailadresse scheint <strong>ungültig</strong> zu sein.";  
     $checkmail=false;  
    }  
  }

Dann kommt die Fehlermeldung: "Parse error: syntax error, unexpected '[', expecting ')' in /kunden/12345/webseiten/eingabepruefung.php on line... " - was in diesem Fall die Zeile "function check_email($_POST['mail'])" wäre.

Woran liegt das bitte? Was genau ist beim 2. Code falsch?

Danke für Hilfe!

Gustav Gans

  1. Hi,

    Wenn ich die Variable aber NICHT umschreibe und das $_POST['mail'] DIREKT verwende, wenn ich es also SO mache =>

    Dann ist das hier unsinnig:

    else
      {
       function check_email($_POST['mail'])

    An der Stelle wird die Funktion definiert, und deren Parametername solltest du natuerlich so lassen, wie er ist.

    return preg_match("/^$regex$/",$_POST['mail']);

    Und auch hier innerhalb der Funktion wird natuerlich der Parameter weiterhin so verwendet, wie er uebergeben wurde - also $email.

    MfG ChrisB

    --
    „This is the author's opinion, not necessarily that of Starbucks.“
    1. Hallo!

      Und auch hier innerhalb der Funktion wird natuerlich der Parameter weiterhin so verwendet, wie er uebergeben wurde - also $email.

      Verstehe. Hab das jetzt auch nochmal im php-Manual nachgelesen. Danke!

      Um einen Thread zu spareen, stell ich noch eine 2. Frage hier:

      Wenn ich einen Eintrag aus einer Textarea eines Formulars bei einer Vorschau einfach nur mit htmlspecialchars($_POST['eintrag']) ausgebe, wird ja alles in einer Wurst geschrieben.

      Also schreibe ich bei der Vorschau nl2br(htmlspecialchars($_POST['eintrag'])).

      Wenn ich mir jetzt aber den Quelltext einer Beispielvorschau ansehe, dann sieht das (verkürzt) so aus:

       <body>  
        <hr />  
        <h3>Vorschau</h3>  
        <hr />  
        <div class="vorschau">  
         <h4>Ihr Eintrag:</h4>  
         <p>Hallo Welt!<br />  
      <br />  
      test</p>  
        </div>  
       </body>
      

      Das heißt, er macht mir jetzt zwar brav die <br />s, zerreißt mir aber den "optischen Aufbau" des Quelltextes. Ich bilde mir ein, ich habe es irgendwann schon mal geschafft, folgendes Ergebnis zu bekommen:

       <body>  
        <hr />  
        <h3>Vorschau</h3>  
        <hr />  
        <div class="vorschau">  
         <h4>Ihr Eintrag:</h4>  
         <p>Hallo Welt!<br /><br />test</p>  
        </div>  
       </body>
      

      Also daß die <br />s erzeugt werden, aber der Quelltext ohne die Zeilenumbrüche entsteht. Wie geht das blos????

      Gustav Gans

      1. Hi,

        Also schreibe ich bei der Vorschau nl2br(htmlspecialchars($_POST['eintrag'])).

        Das heißt, er macht mir jetzt zwar brav die <br />s, zerreißt mir aber den "optischen Aufbau" des Quelltextes.

        nl2br ersetzt die Zeilenumbruchzeichen nicht, sondern fuegt ihn <br /> hinzu.

        Also daß die <br />s erzeugt werden, aber der Quelltext ohne die Zeilenumbrüche entsteht. Wie geht das blos????

        nl2br anwenden, und anschliessen Zeilenumbruchzeichen rausloeschen.
        Oder gleich selber machen, Zeilenumbruchzeichen durch <br /> *ersetzen*.
        Dabei aber die unterschiedlichen moeglichen Arten von Zeilenumbruchzeichen beruecksichtigen.

        MfG ChrisB

        --
        „This is the author's opinion, not necessarily that of Starbucks.“
        1. Hallo!
          Zu Deinem 2. Vorschlag, Zeilenumbruchzeichen durch <br /> *ersetzen*, habe ich jetzt etwas länger suchen müssen. :-)

          Doch nun habe ich im php-Manual bei der str_replace Funktion bei Beispiel 1 unter "// Reihenfolge von Ersetzungen" was gefunden. Mein Code sieht jetzt SO aus und ich habe EXAKT das gewünschte Ergebnis, nämlich dazugekommene <br />s bei der Usereingabe und keine Zeilenumbrüche im Quelltext:

          echo"   <h4>Ihr Eintrag:</h4>\n";  
          $order   = array("\r\n", "\n", "\r");  
          $replace = '<br />';  
          $usereintrag=str_replace($order, $replace, htmlspecialchars($_POST['eintrag']));  
          echo"   <p>".$usereintrag."</p>\n";
          

          Ich will nur wissen: Ist das eh so, wie Du es gemeint hast?

          Und meine Abschlußfrage: Auf einer anderen Seite im Internet hat ein User die selbe Frage gestelt wie ich und bekam als Antwort den Hinweis auf die rtrim-Funktion. Ich nehme aber nicht an, daß die helfen würde, oder? (Abgesehen davon, daß ich eh schon deas gewünschte Ergebnis habe)

          Grüße

          Gustav Gans

          1. Hallo!

            Ich habe DOCH noch ein Folgeproblem. :-(

            Ganz prinzipiell: Ist es möglich, in EINER EINZIGEN Quellcodezeile ein mehrzeiliges Textfeld mit einem Text, der auch mehrere Zeilenumbrüche hat, zu definieren?

            Also wenn ich zB ein mehrzeiliges Textfeld folgendermaßen vorbelegen will:

            +++++++++++++++++++++++++++++++++++++++++
            +Hallo Welt!                            +
            +                                       +
            +Das ist eine erste Zeile.              +
            +Das die zweite.                        +
            +                                       +
            +Liebe Grüße                            +
            +                                       +
            +Max Mustermann                         +
            +++++++++++++++++++++++++++++++++++++++++

            Kann ich das in EINER EINZIGEN Quellcodezeile OHNE Umbruch vorbelegen?

            Ich würde das DESHALB gerne tun, um bei einer Vorschau eines ausgefüllten Formulars für ein Gästebuch auch den Gästebucheintrag aus dem mehrzeiligen Textfeld des Formulars nicht nur in der Vorschau zu zeigen (das hab ich mit ChrisB`s Hilfe ja schon geschafft), sondern auch gleich nochmal im darunterliegenden Formular als Text vorzubelegen OHNE irgendwelche Zeilenumbrüche im Quelltext.

            Oder mit anderen Worten: Unter der Vorschau befindet sich wieder das Formular, diesmal schon mit den vorher eingegebenen Daten und wenn der User vorher im Textfeld Zeilenumbrüche gemacht hat, soll der Text jetzt 1:1 so im Formular erscheinen, im QUellcode aber in EINER Zeile sein.

            Geht das?

            Gustav Gans

            1. Hi,

              Ganz prinzipiell: Ist es möglich, in EINER EINZIGEN Quellcodezeile ein mehrzeiliges Textfeld mit einem Text, der auch mehrere Zeilenumbrüche hat, zu definieren?

              Nein.
              (Es sei denn, du wuerdest JavaScript zu Hilfe nehmen wollen - willst du aber nicht, denn das waere in diesem Falle grob schwachsinnig.)

              Ich würde das DESHALB gerne tun, um bei einer Vorschau eines ausgefüllten Formulars für ein Gästebuch auch den Gästebucheintrag aus dem mehrzeiligen Textfeld des Formulars nicht nur in der Vorschau zu zeigen (das hab ich mit ChrisB`s Hilfe ja schon geschafft), sondern auch gleich nochmal im darunterliegenden Formular als Text vorzubelegen OHNE irgendwelche Zeilenumbrüche im Quelltext.

              Lasse dich gegen deine Zeilenumbruchphobie behandeln - sie nimmt Zuege an, die nicht mehr gut fuer dich sind.

              MfG ChrisB

              --
              „This is the author's opinion, not necessarily that of Starbucks.“
              1. Hallo!

                Ganz prinzipiell: Ist es möglich, in EINER EINZIGEN Quellcodezeile ein mehrzeiliges Textfeld mit einem Text, der auch mehrere Zeilenumbrüche hat, zu definieren?

                Nein.

                Schade. Aber gut zu wissen. Dann muß ich diese Tatsache wohl akzeptieren. :-(

                (Es sei denn, du wuerdest JavaScript zu Hilfe nehmen wollen - willst du aber nicht, denn das waere in diesem Falle grob schwachsinnig.)

                Stimmt, will ich nicht. Ich will Javascript eigentlich NIE verwenden.

                Ich würde das DESHALB gerne tun, um bei einer Vorschau eines ausgefüllten Formulars für ein Gästebuch auch den Gästebucheintrag aus dem mehrzeiligen Textfeld des Formulars nicht nur in der Vorschau zu zeigen (das hab ich mit ChrisB`s Hilfe ja schon geschafft), sondern auch gleich nochmal im darunterliegenden Formular als Text vorzubelegen OHNE irgendwelche Zeilenumbrüche im Quelltext.

                Lasse dich gegen deine Zeilenumbruchphobie behandeln - sie nimmt Zuege an, die nicht mehr gut fuer dich sind.

                *grins* Ja, Du hast eh Recht, Chris. Es ist nur so, daß ich da so ein optischer Perfektionist bin und es mir in Fleisch und Blut übergegangen ist, nicht nur semantisches HTML zu schreiben, sondern einen Quelltext auch optisch so zu gestalten, daß er perfekt übersichtlich und logisch gegliedert ist. Und das ist halt nicht der Fall, wenn hier mein System durch von mir nicht gewollte Zeilenumbrüche "zerstört" wird und so ein "zerrissener Quellcode" entsteht.

                Wenn ich dann also SOWAS (siehe den teil bei der Vorbelegung des mehrzeiligen Eingabefeldes) sehe:

                  <form action="formular.php" method="post" accept-charset="utf-8">  
                   <fieldset>  
                    <legend>Ihr Eintrag ins Gästebuch</legend>  
                    <label for="name">Ihr Name:</label><br /><input type="text" size="40" maxlength="40" id="name" name="name" value="Hans Huber" tabindex="1" /><br />  
                    <label for="stadt">Ihre Stadt:</label><br /><input type="text" size="40" maxlength="40" id="stadt" name="stadt" value="Tell" tabindex="2" /><br />    <label for="mail">Ihre Mailadresse:</label><br /><input type="text" size="40" maxlength="40" id="mail" name="mail" value="hans@jfj.com" tabindex="3" /><br />  
                  
                    <label for="permit">Dürfen wir Ihre Mailadresse veröffentlichen?</label><br /><input type="checkbox" id="permit" name="permit" value="1" tabindex="4" /> ja<br />  
                    <label for="eintrag">Ihr Eintrag:<br /></label><textarea id="eintrag" name="eintrag" cols="50" rows="10" tabindex="5">Hallo Michi!  
                  
                Das ist ein Test.  
                  
                  
                  
                Grüße  
                  
                Hans</textarea><br />  
                   </fieldset>  
                   <p><input class="button" type="submit" id="vorschau" name="submit[0]" title="Vorschau anzeigen" value="Vorschau" /></p>  
                   <p><input class="button" type="submit" id="absenden" name="submit[0]" title="Jetzt absenden" value="Absenden" /></p>  
                  </form>
                

                Das bereitet mir körperliche Schnmerzen. Und wenns 100 mal valide ist. Naja, vielleicht bin ich ja um 10 Ecken mit Herrn Monk oder mit Woody Allen verwandt. *g*

                Liebe Grüße

                Gustav Gans

  2. Hello,

    function check_email($email)
        {
        [...]
        }
       if(check_email($email))
      }[/code]

    klar funktioniert das, du bist dir nur nicht ganz bewusst, was du hier umschreibst. Die Funktion deklariert für sich einen einzelnen Parameter namens "email". Diese Parameter könnte auch "pruefdashier" heißen, der Code würde immer noch funktionieren, solange die Änderung konsequent innerhalb der Funktion umgesetzt ist. Die aufrufende Stelle check_email(...) hat NICHTS mit der Benennung des Parameters zu tun.

    function check_email($_POST['mail'])

    dementsprechend ist es hier falsch.

    return preg_match("/^$regex$/",$_POST['mail']);

    das hier wiederum würde funktionieren, das $_POST ein superglobal und damit überall verfügbar ist.

    if(check_email($_POST['mail']))

    ...damit wäre aber das hier überflüssig, der Parameter würde gar nicht mehr gebraucht.

    Fazit: die einzig zu ändernde Stelle ist der AUFRUF von check_email.

    MfG
    Rouven

    --
    -------------------
    sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
    There's no such thing as a free lunch  --  Milton Friedman
    1. Danke für die Antwort! Das zeigt mir, daß ich die Erklärung von ChrisB richtig verstanden habe!

  3. echo $begrüßung;

    Noch ein anderer Aspekt:

    if(...)
      {
       function check_email($email)
        { ... }
       if(check_email($email))
        { ... }

    Eine Funktion kann zwar innerhalb einer anderen Kontrollstruktur definiert werden, das ist aber nicht unbedingt besonders guter Stil und in diesem Fall auch nicht notwendig. Funktionen dienen dazu, wiederkehrende und/oder in sich abgeschlossene Verarbeitungsschritte zu kapseln, und damit auch, ein Programm zu strukturieren. Die Definition stellt man am besten an den Anfang oder lagert sie in eine Include-Datei aus. Im Hauptprogrammteil findet dann nur noch ihr ein- oder mehrmaliger Aufruf statt.

    echo "$verabschiedung $name";

  4. Hallo,

    Ich beziehe meine Frage auf den Artikel E-Mail-Kontrolle von Christian Kruse, erschienen auf SELFHTML.

    ich möchte an dieser Stelle auf den Weblog-Artikel "Validierung von eMail-Adressen (Selfforumssieb)" hinweisen, da auch Christians Prüfung - wie fast alle dieser Prüfungen - fehlerhaft ist.

    In folgender Zeile steckt ein Fehler:

    $dom_tldpart   = '[a-zA-Z]{2,5}';

    Und nein, es ist keine gute Idee, einfach die 5 durch eine 6 zu ersetzen - die Diskussion darüber kann man im Weblog und den dort verlinkten Ressourcen nachlesen.

    Freundliche Grüße

    Vinzenz

    1. Hi!

      ich möchte an dieser Stelle auf den Weblog-Artikel "Validierung von eMail-Adressen (Selfforumssieb)" hinweisen, da auch Christians Prüfung - wie fast alle dieser Prüfungen - fehlerhaft ist.

      In folgender Zeile steckt ein Fehler:

      $dom_tldpart   = '[a-zA-Z]{2,5}';
      Und nein, es ist keine gute Idee, einfach die 5 durch eine 6 zu ersetzen - die Diskussion darüber kann man im Weblog und den dort verlinkten Ressourcen nachlesen.

      Das klingt sehr interessant, leider steht dort nicht, wie man den Code entsprechend alternativ umschreiben soll. :-(

      Gustav Gans

      1. Hi,

        In folgender Zeile steckt ein Fehler:

        $dom_tldpart   = '[a-zA-Z]{2,5}';
        Und nein, es ist keine gute Idee, einfach die 5 durch eine 6 zu ersetzen - die Diskussion darüber kann man im Weblog und den dort verlinkten Ressourcen nachlesen.

        Das klingt sehr interessant, leider steht dort nicht, wie man den Code entsprechend alternativ umschreiben soll. :-(

        Dafuer steht da erklaert, warum man sich zu "genaue" Ueberpruefungen an der Stelle einfach sparen sollte - weil sie unsinnig sind.

        MfG ChrisB

        --
        „This is the author's opinion, not necessarily that of Starbucks.“
      2. Moin!

        Hi!

        ich möchte an dieser Stelle auf den Weblog-Artikel "Validierung von eMail-Adressen (Selfforumssieb)" hinweisen, da auch Christians Prüfung - wie fast alle dieser Prüfungen - fehlerhaft ist.

        In folgender Zeile steckt ein Fehler:

        $dom_tldpart   = '[a-zA-Z]{2,5}';
        Und nein, es ist keine gute Idee, einfach die 5 durch eine 6 zu ersetzen - die Diskussion darüber kann man im Weblog und den dort verlinkten Ressourcen nachlesen.

        Das klingt sehr interessant, leider steht dort nicht, wie man den Code entsprechend alternativ umschreiben soll. :-(

        Ich glaube, nach dem Lesen meines Kommentars lässt du das auch lieber.

        Es ist einfach nicht sinnvoll, auf mehr zu prüfen als "Kommt ein @ in dem Adressstring vor?" und "Kommt ein Punkt hinter dem @?"

        Wenn mehr geprüft werden soll: Schick eine Email an die Adresse, lass den Empfänger einen Link mit nicht erratbarer ID klicken, und registriere den Aufruf dieser eindeutigen Adresse. Erst danach ist dir bekannt, das die Mailadresse korrekt funktioniert.

        - Sven Rautenberg

  5. Guten Tag,

    Moin!

    Ich beziehe meine Frage auf den Artikel E-Mail-Kontrolle von Christian Kruse, erschienen auf SELFHTML.

    Was spricht dagegen, einen Filter mit FILTER_VALIDATE_EMAIL zu verwenden? Der Filter prüft zwar auch nur, ob die Adresse richtig aussieht, ist dafür aber sehr performant.

    Gruß
    Christoph Jeschke

    --
    Zend Certified Engineer
    Certified Urchin Admin