Graf Zahl: Fehler in PHP Kontaktformular

Hallo,

ich habe nun wirklich schon ewig geschaut und nach hilfen gesucht aber ich kann den fehler in meinem Kontaktformular nicht finden und es ist mittlerweile mitten in der Nacht und ich bin entsprechend fertig :S
Ich hoffe das evtl. hier jemand sieht was ich falsch gemacht habe, der Fehler ist dass immer die Fehler meldung kommt also die oberen Prüfungen scheinen alle soweit korrekt ausgeführt zu werden.

  
<?php>  
  
    $lost = "sample@test.de";  
  
    //Variablen  
    $name    = $_POST["name"];  
    $email   = $_POST["email"];  
    $msg     = $_POST["msg"];  
    $website = $_POST["website"];  
    $theme   = $_POST["theme"];  
    $subject = $_POST["subject"];  
    $message = $_POST["message"];  
  
    //Felder leer?  
    if(($name == "") OR ($email == "") OR ($subject == ""))  
        {  
            echo "Alle mit * markierten Felder m&uuml;ssen ausgef&uuml;llt sein!";  
            die;  
        }  
  
    //Nachricht leer?  
    if(($message == ""))  
        {  
            echo "Deine Nachricht sollte nicht leer sein ;-)";  
            die;  
        }  
  
    //E Mail adresse korrekt?  
    if($email != "")  
        {  
            $pos2 = strpos($email, "@");  
            $pos3 = strpos($email, ".");  
  
            if(($pos2 == false) OR ($pos3 == false))  
                {  
                    echo "In deiner E-Mail Adresse gibt es einen Fehler";  
                    die;  
                }  
        }  
  
    $betreff    = " '$theme' : '$subject' ";  
    $nachricht  = "  
                Name      : '$name'  
                E-Mail    : '$email'  
                MSG       : '$msg'  
                Website   : '$website'  
                Nachricht :  
                '$message'  
                ";  
  
    $from = "'$email'";  
    $mailfunction = mail($lost, $betreff, $nachricht, $from);  
    if($mailfunction)  
        {  
            echo "Erfolg";  
        }else  
        {  
            echo "Fehler";  
            die;  
        }  
  
?>  

  1. Hallo!

    //Variablen
        $name    = $_POST["name"];
        $email   = $_POST["email"];
        $msg     = $_POST["msg"];
        $website = $_POST["website"];
        $theme   = $_POST["theme"];
        $subject = $_POST["subject"];
        $message = $_POST["message"];

      
    Wozu dieses kopieren der Variablen? Damit verschleierst du im Script effektiv deren Herkunft und verbrauchst unnötig Speicher.  
    Benutze stattdessen direkt das Array.  
      
      
    
    > ~~~php
      
    
    >    die;  
    > 
    
    

    Es ist nicht schön sein Script aufgrund einer Fehlermeldung sterben zu lassen. Führe stattdessen Code aus der auf den Fehler reagiert.

    echo "In deiner E-Mail Adresse gibt es einen Fehler";

      
    Rein technisch gesehen, kannst du das anhand deiner Prüfung nicht wissen. localhost wäre auch eine gültige email-Adresse und enthält weder ein "@" noch ein ".".  
      
    
    > ~~~php
      
    
    >    $from = "'$email'";  
    > 
    
    

    ´´Um eine E-Mail zu senden, muss die E-Mail einen From-Header enthalten.``

    Bei dir steht allerdings ein ungefilterter String in einfachen Anführungszeichen. Ein offenes Tor für Spambots. Es ist ganz einfach möglich, dass der Benutzer weitere Header sendet. Du solltest also zumindest dringend Zeilenumbrüche (\r und \n) filtern.
    Richtig wäre z.B. $from = 'From: example@domain.tld';

    Grüße, Matze

    1. Tach!

      echo "In deiner E-Mail Adresse gibt es einen Fehler";

      
      > Rein technisch gesehen, kannst du das anhand deiner Prüfung nicht wissen. localhost wäre auch eine gültige email-Adresse und enthält weder ein "@" noch ein ".".  
        
      Rein praktisch gesehen, kommen lokale Adressen bei einem Kontaktformular nur ganz selten vor. Die Prüfung ist jedoch trotzdem nicht so wahnsinnig nützlich, weil mit Syntaxprüfungen allein die Gültigkeit von Adressen nicht festgestellt werden kann.  
        
      
      > > ~~~php
        
      
      > >    $from = "'$email'";  
      > > 
      
      

      ´´Um eine E-Mail zu senden, muss die E-Mail einen From-Header enthalten.``

      Bei dir steht allerdings ein ungefilterter String in einfachen Anführungszeichen. Ein offenes Tor für Spambots. Es ist ganz einfach möglich, dass der Benutzer weitere Header sendet. Du solltest also zumindest dringend Zeilenumbrüche (\r und \n) filtern.

      Wenn \r oder \n in solchen in Header einzufügenden Daten vorkommen, kann man das Script kommentarlos beenden. Ein Spam-Bot interessiert sich nicht für korrekte HTML-Syntax oder eine Fehlermeldung. Er muss einfach nur an seinem Tun gehindert werden.

      Ich hoffe das evtl. hier jemand sieht was ich falsch gemacht habe, der Fehler ist dass immer die Fehler meldung kommt also die oberen Prüfungen scheinen alle soweit korrekt ausgeführt zu werden.

      Dass das Script im "Fehler" endet, liegt vermutlich nicht an der Datenverarbeitung des Scripts. Und man muss sich auch nicht auf den Schein verlassen, man kann die Werte auch mit einer Kontrollausgabe prüfen. Dass das Script im "Fehler"-Zweig landet liegt am Rückgabewert von mail() - auch den kann man sich anzeigen lassen: var_dump($mailfunction); - Und dann schaut man im Handbuch nach, wann mail() mit false antwortet: wenn es die Mail nicht senden konnte. Der Hauptgrund dafür ist meist ein nicht richtig konfiguriertes System (PHP findet den MTA (Mail Transfer Agent) nicht).

      dedlfix.

      1. Hallo!

        Wenn \r oder \n in solchen in Header einzufügenden Daten vorkommen, kann man das Script kommentarlos beenden. Ein Spam-Bot interessiert sich nicht für korrekte HTML-Syntax oder eine Fehlermeldung. Er muss einfach nur an seinem Tun gehindert werden.

        Du hast natürlich recht! Kein Einwand.

        Der Hauptgrund dafür ist meist ein nicht richtig konfiguriertes System (PHP findet den MTA (Mail Transfer Agent) nicht).

        Das sehe ich allerdings anders. "Meist" arbeitet man mit einem fertig eingerichteten System eines Massenhosters. Die wenigstens werden ihre Server selbst aufsetzen und konfigurieren. Für den durchschnittlichen Anwender ist das einfach zu viel. Anders sieht es natürlich mit lokalen Testservern (XAMPP u.ä.) aus. Da wirst du wieder recht haben.

        Grüße, Matze

        1. Tach!

          Der Hauptgrund dafür ist meist ein nicht richtig konfiguriertes System (PHP findet den MTA (Mail Transfer Agent) nicht).
          Das sehe ich allerdings anders. "Meist" arbeitet man mit einem fertig eingerichteten System eines Massenhosters. Die wenigstens werden ihre Server selbst aufsetzen und konfigurieren. Für den durchschnittlichen Anwender ist das einfach zu viel.

          Welchen anderen Grund siehst du denn, dass mail() misslingen kann? Gut, dass der MTA die Annahme verweigert, wäre noch ein Grund, aber den halte ich für relativ unwahrscheinlich. Wenn man mit einem fertig eingerichteten System arbeitet, wird man üblicherwiese auf keine Ablehnung seitens des MTA treffen. Wenn doch solch ein Szenario vorliegt, dann kann das sowie nur mit dem Systemverwalter geklärt werden.

          Anders sieht es natürlich mit lokalen Testservern (XAMPP u.ä.) aus. Da wirst du wieder recht haben.

          Das vermute ich auch im vorliegenden Fall. Wenn ich meine gefühlte Ursachen-für-false-Statistik befrage, dominieren da eindeutig Windows-Systeme, auf denen kein MTA installiert wurde.

          dedlfix.

          1. Welchen anderen Grund siehst du denn, dass mail() misslingen kann?

            Ganz einfach fehlerhafte oder fehlende Werte so, dass die email nicht "für den Versand akzeptiert wurde".

            Grüße, Matze

            1. Tach!

              Ganz einfach fehlerhafte oder fehlende Werte so, dass die email nicht "für den Versand akzeptiert wurde".

              Du meinst, die fehlerhafte From-Zeile ist die Ursache? Mein MTA hat ohne zu klagen, nur eine reine Email-Adresse als $additional_headers geschluckt. Diese Adresse landete dann im Body und nicht im Header, aber egal.

              dedlfix.

              1. Du meinst, die fehlerhafte From-Zeile ist die Ursache? Mein MTA hat ohne zu klagen, nur eine reine Email-Adresse als $additional_headers geschluckt. Diese Adresse landete dann im Body und nicht im Header, aber egal.

                Ja, meine ich z.B.. Ein fehlerhafter Empfänger dürfte allerdings auch eine Möglichkeit sein die Funktion fehlschlagen zu lassen.
                Dein MTA wird in dem Fall aber den Absender daher beziehen:

                ´´Dies kann entweder durch Setzen eines additional_headers-Parameters oder durch Setzen eines Standardwertes in der php.ini geschehen.``

                Im Zweifel vermutlich einfach nur localhost.

                Grüße, Matze

                1. Tach!

                  Du meinst, die fehlerhafte From-Zeile ist die Ursache?
                  Ja, meine ich z.B.. Ein fehlerhafter Empfänger dürfte allerdings auch eine Möglichkeit sein die Funktion fehlschlagen zu lassen.

                  Ich nehme nicht an, dass der OP so unerfahren ist, dass er die Syntax einer Mailadresse nicht ausreichend korrekt zu notieren vermag. Weiterhin prüft der MTA _nicht_ bereits beim Entgegennehmen der Mail die Auslieferbarkeit. Sonst bräuchte man keinen MTA. Vielmehr nimmt dieser die Mail entgegen und mail() meldet true. Die Aufgabe eines MTA ist, die Mail abzuliefern, und dabei kann er durchaus mehrere Versuche über einen längeren Zeitraum hin unternehmen. Das muss er sogar, wenn der Empfangsserver Graylisting aktiviert hat. In dem Fall prüft lezterer die Ernsthaftigkeit des Zustellversuchs, indem er erst ein- oder zweimal den Empfang verweigert. "Wenn du wirklich willst, probierst du es auch mehrfach." Damit hält man sich zum Beispiel eine ganze Menge dummer Fire-and-forget-Spambots vom Leibe. Auch eine temporäre Fehlfunktion des Emfangsservers bekommt man durch die mehrfachen Zustellversuche mitunter umgangen.

                  Das heißt nun für das Zusammenspiel von mail() und MTA, dass mail() nicht warten kann, bis der MTA Erfolg hatte. So lange wartet kein Anwender und auch Timeouts schlagen zu, bevor der MTA aufgibt. mail() übergibt an den MTA und kehrt gleich wieder zurück. (Wie im echten Leben, da bleibt man auch nicht neben dem Briefkasten stehen und wartet auf eine Auslieferungsbestätigung.) Folglich heißt das, dass (bei handelsüblichen MTAs) die Nichtauslieferbarkeit einer Mail von mail() nicht mit einem false gemeldet wird. Dieses Szenario ist also sehr unwahrscheinlich die Ursache für das false des OP.

                  dedlfix.

                  1. Weiterhin prüft der MTA _nicht_ bereits beim Entgegennehmen der Mail die Auslieferbarkeit. Sonst bräuchte man keinen MTA. Vielmehr nimmt dieser die Mail entgegen und mail() meldet true.

                    Ich sagte ja auch nicht, dass der MTA die Auslieferbarkeit überprüft, sondern das mail() prüft ob alle erforderlichen Daten im korrekten Zustand sind um prinzipiell vom MTA ausgeliefert zu werden, also ´´für den Versand akzeptiert wurde``.
                    Der MTA wird wohl kaum bemüht wenn mail() Quark erhält.

                    Oder habe ich dich falsch verstanden?

                    Grüße, Matze

                    1. Tach!

                      Ich sagte ja auch nicht, dass der MTA die Auslieferbarkeit überprüft, sondern das mail() prüft ob alle erforderlichen Daten im korrekten Zustand sind um prinzipiell vom MTA ausgeliefert zu werden, also ´´für den Versand akzeptiert wurde``. Der MTA wird wohl kaum bemüht wenn mail() Quark erhält.

                      Was genau kann er aber im vorliegenden Fall prüfen? Die Email-Adresse? Ich gehe davon aus, dass das nicht die Ursache ist. Man muss sich schon sehr anstrengen, um unwillentlich eine derart falsche Adresse zu produzieren, die kein MTA ausliefern kann, und sie deshalb gleich beim Übergeben ablehnt. Das Subject wird von PHP in eine harmlose Form gebracht. Der Body interessiert sowieso nicht. Die Additional Headers, trotz ihres formalen Fehlers halte ich auch nicht für die false-Ursache.

                      Lassen wir es erst einmal dabei. Ohne dass der OP auf die bisherigen Vermutungen eingeht, werden wir es sowieso nicht erfahren.

                      dedlfix.

                      1. [latex]Mae  govannen![/latex]

                        Die Additional Headers, trotz ihres formalen Fehlers halte ich auch nicht für die false-Ursache.

                        Kommt drauf an. Mein Hoster verweigert bspw. generell den Versand, wenn mail() über das Script/die PHP-Konfiguration nicht explizit einen bestimmten Parameter (eine der auf mich eingetragenen E-Mail-Adressen)  in den „additional Headers“ übergeben bekommt

                        Stur lächeln und winken, Männer!
                        Kai

                        --
                        var jQuery = $(hit);
                        I am Pentium of Borg. Division is futile. You will be approximated.
                        SelfHTML-Forum-Stylesheet
                        1. Tach!

                          Die Additional Headers, trotz ihres formalen Fehlers halte ich auch nicht für die false-Ursache.
                          Kommt drauf an. Mein Hoster verweigert bspw. generell den Versand, wenn mail() über das Script/die PHP-Konfiguration nicht explizit einen bestimmten Parameter (eine der auf mich eingetragenen E-Mail-Adressen)  in den „additional Headers“ übergeben bekommt

                          Ok, ich hatte mich da grad zu sehr auf die Windows-ohne-MTA-Theorie versteift. Der Fall des Pflicht-Parameters ist auch noch eine gängige Fehlermöglichkeit. Wobei ich mich da gerade (ohne eine gescheite Antwort zu finden), welchen Nutzen eine solche Pflichtangabe hat. Wenn jemand Zugriff auf den Server bekommt, kann er die Pflichtadresse auch dem Quellcode entnehmen und sich damit fremdausweisen. Auch gegen spionierende Mithostlinge hilft das nur wenn die Dateiberechtigungen konsequent richtig gesetzt werden (und nicht z.B. auf pauschal 0777). Bringt der Pflichtparameter wirklich mehr Nutzen als es die rechtmäßigen SMTP-Server-Verwender gängelt?

                          dedlfix.

      2. Rein praktisch gesehen, kommen lokale Adressen bei einem Kontaktformular nur ganz selten vor. Die Prüfung ist jedoch trotzdem nicht so wahnsinnig nützlich, weil mit Syntaxprüfungen allein die Gültigkeit von Adressen nicht festgestellt werden kann.

        Huch, dazu hab ich doch eigentlich auch was geschrieben. Hab ich wohl irgendwie wieder gelöscht.

        Ich denke, wenn man vom praktischen Fall der Prüfung ausgeht, geht eine Prüfung nach @ und . schon in Ordnung. Allerdings ist sie unzureichend umgesetzt. Sein Script würde "@." auch als gültig anerkennen. Man sollte dann wenigstens auch prüfen ob vor, nach und zwischen den Zeichen noch Zeichen stehen und whitespaces vorher filtern.

        Grüße, Matze

        1. Tach!

          Ich denke, wenn man vom praktischen Fall der Prüfung ausgeht, geht eine Prüfung nach @ und . schon in Ordnung. Allerdings ist sie unzureichend umgesetzt. Sein Script würde "@." auch als gültig anerkennen.

          Oder auch .@ oder jede beliebige andere Kombination von . oder @ am Anfang, egal ob noch was folgt oder nicht.

          $pos2 = strpos($email, "@");
                      $pos3 = strpos($email, ".");

          if(($pos2 == false) OR ($pos3 == false))
                          {
                              echo "In deiner E-Mail Adresse gibt es einen Fehler";
                              die;
                          }

          Wenn @ oder . am Anfang steht, liefert strpos() den Wert 0. $pos2 oder $pos3 ist also 0, was einem false entspricht, und eins davon reicht, um die Bedingung zu erfüllen.

          Zudem ist die Aussage "In deiner E-Mail Adresse gibt es einen Fehler" nicht sehr anwenderfreundlich. "Ich hab zwar auf konkrete Bedingungen geprüft, aber ich sag dir nicht, was falsch ist. Was falsch ist, lieber Anwender, musst du schon selbst herausfinden."

          dedlfix.

          1. Wenn @ oder . am Anfang steht, liefert strpos() den Wert 0. $pos2 oder $pos3 ist also 0, was einem false entspricht, und eins davon reicht, um die Bedingung zu erfüllen.

            Du hast natürlich, wieder mal, recht^^ Ich vergaß die Typumwandlung von PHP.
            Allerdings ändert das prinzipell nichts an der Aussage, dass die Überprüfung unzureichend ist.
            1 beliebiges Zeichen, inklusive whitespace, am Anfang gefolgt von .@ oder @. führt zu true. Es dürften sogar mehrere @ vorkommen. Mehrere . sind hingegen gängige Praxis und stören nicht.

            Danke für die Korrektur!

            Grüße, Matze