Martin_Online: eMail mit PHP verschicken

Ich möchte meine Seite mit einem Kontaktformular erweitern, einige haben mir von der PHP Mail Funktion abgeraten, soll lieber

http://phpmailer.worxware.com/ Oder http://swiftmailer.org/ nehmen.

Was könnt ihr mir empfehlen? Was ist in beiden der Unterscheid und warum nicht die PHP Mail Funktion?

  1. Meine Herren!

    Ich möchte meine Seite mit einem Kontaktformular erweitern, einige haben mir von der PHP Mail Funktion abgeraten … und warum nicht die PHP Mail Funktion?

    Warum hast du das nicht gleich bei den Kritikern erfragt? ;)

    Hier ist meine Sicht auf die Dinge:
    PHPs eigene mail-Funktion ist sehr spartanisch. Sehen wir uns mal die Signatur an:

    bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )

    Aha: Empfänger ($to), Betreff ($subject) und Mail-Text ($message) können wir direkt angeben. Das ist schon mal gut, nicht so offensichtlich ist, wie wir die Absender-Adresse oder weitere Empfänger angeben könnten. Diese Informationen würden wir als $additional_headers übergeben. Der Wert dieser Variablen unterliegt strengen Syntax-Regeln und PHP leistet uns keinerlei Hilfestellung dabei, diese einzuhalten. Um die Absender-Adresse anzugeben könnten wir zum Beispiel folgenden Code benutzen:

    $additional_headers = 'From: webmaster@example.com\r\n';

    für einen weiteren Empfänger:

    $additional_headers .= 'Cc: uwe@example.com' . "\r\n";

    Noch ist das alles nicht so kompliziert, aber wenn es dann plötzlich darum geht mal eine HTML-Mail statt einer reinen Text-Mail zu verschicken, wenn noch andere versteckte Adressaten hinzukommen oder wenn Anhänge mitgeschickt werden müssen, dann wird es sehr unübersichtlich, wenn wir nach diesem Schema fortfahren müssen.

    Deshalb gibt es eine Reihe Bibliotheken, die versuchen dieses Verhalten zu kapseln und mit einer ausdrucksstarken API zugänglicher zu machen.

    --
    “All right, then, I'll go to hell.” – Huck Finn
    1. Danke für deine Antwort, warum ich nicht direkt gefragt habe, eine sehr gute Frage. Ich weiß es nicht. Sehe diesen leider erst Anfang Juni wieder, deshalb hier meine Frage.

      Ja, ich möchte meine eMails gerne als HTML verschicken, auch wenn hier die Meinungen wahrscheinlich sehr auseinander gehen, mir gefallen formatierte eMails besser als schlichte Textnachrichten.

      Könntest du mir vielleicht noch sagen wie ich $additional_headers eine HTML eMail raus schicken kann, oder sagst du nehme dazu lieber ein die von dir genannten Mailer?

      1. Meine Herren!

        Danke für deine Antwort, warum ich nicht direkt gefragt habe, eine sehr gute Frage. Ich weiß es nicht. Sehe diesen leider erst Anfang Juni wieder, deshalb hier meine Frage.

        Beim nächsten mal weißt du 's besser. Nachhaken drückt auch gesundes Interesse aus.

        Könntest du mir vielleicht noch sagen wie ich $additional_headers eine HTML eMail raus schicken kann

        Das könnte ich, aber ich denke dir ist mehr geholfen, wenn du selber lernst solche Dinge in Erfahrung zu bringen. Du weißt schon, die ganze Geschichte mit dem Mann und dem Fisch und der Angel.

        oder sagst du nehme dazu lieber ein die von dir genannten Mailer?

        Das wiederum könnte ich nicht guten Gewissens, weil ich selber zu wenig Erfahrung mit diesen Bibliotheken habe.

        --
        “All right, then, I'll go to hell.” – Huck Finn
        1. Moin!

          oder sagst du nehme dazu lieber ein die von dir genannten Mailer?

          Das wiederum könnte ich nicht guten Gewissens, weil ich selber zu wenig Erfahrung mit diesen Bibliotheken habe.

          Hast du denn ausreichende Kenntnisse zum sicheren Zusammenbauen von Multipart-Mails inkl. Härtung gegen Header-Injection?

          Sowas schüttelt man auch nicht mal eben aus dem Ärmel - die Bibliotheken würden sowas aber vermutlich bereits implementiert haben.

          Mein Votum ist eindeutig: Nimm eine Bibliothek dafür, mach sowas nicht selbst. Das ist zuviel Aufwand für wenig Nutzen.

          - Sven Rautenberg

          1. hi,

            oder sagst du nehme dazu lieber ein die von dir genannten Mailer?

            Das wiederum könnte ich nicht guten Gewissens, weil ich selber zu wenig Erfahrung mit diesen Bibliotheken habe.

            Hast du denn ausreichende Kenntnisse zum sicheren Zusammenbauen von Multipart-Mails inkl. Härtung gegen Header-Injection?

            Sowas schüttelt man auch nicht mal eben aus dem Ärmel - die Bibliotheken würden sowas aber vermutlich bereits implementiert haben.

            Mein Votum ist eindeutig: Nimm eine Bibliothek dafür, mach sowas nicht selbst. Das ist zuviel Aufwand für wenig Nutzen.

            • Sven Rautenberg
              
            <?php  
            require_once 'Zend/Loader/StandardAutoloader.php';  
            $loader = new Zend\Loader\StandardAutoloader(array('autoregister_zf' => true));  
            $loader->register();  
            //~ use Zend\Mail\Message;  
            //~ $message = new Message();  
              
            use Zend\Mail\Message;  
            use Zend\Mail\Transport\Smtp as SmtpTransport;  
            use Zend\Mail\Transport\SmtpOptions;  
              
            $message = new Message();  
            $message->addTo('test@example.com')  
                    ->addFrom('test2@example.com')  
                    ->setSubject('Greetings and Salutations!')  
                    ->setBody("Sorry, I'm going to be late today!");  
              
            // Setup SMTP transport using LOGIN authentication  
            $transport = new SmtpTransport();  
            $options   = new SmtpOptions(array(  
                'name'              => 'localhost.localdomain',  
                'host'              => 'smtp.example.com',  
                'connection_class'  => 'login',  
                'connection_config' => array(  
                    'username' => 'mail@example.com',  
                    'password' => 'MyPassword',  
                ),  
            ));  
            $transport->setOptions($options);  
            $transport->send($message);  
            //~ var_dump($message);  
            
            

            mfg

            tami

      2. Tach!

        Könntest du mir vielleicht noch sagen wie ich $additional_headers eine HTML eMail raus schicken kann, oder sagst du nehme dazu lieber ein die von dir genannten Mailer?

        Wenn du nicht vorhast, zu erlernen wie man eine Multipart-Mail aufbaut, sondern einfach nur Mails versenden möchtest, kommst du mit einem fertigen Mailer effizienter zu einem brauchbaren Ergebnis.

        dedlfix.

  2. Guten Morgen,

    ich prüfe meine Felder wie folgt:

      
    $errors = array();  
      
            if(empty($_POST['name'])) {  
                $errors[] = "Bitte geben Sie Ihren Namen an";  
            }  
      
            if(empty($_POST['email'])){  
                $errors[] = "Bitte geben sie Ihre eMail Adresse an";  
            } elseif (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) == false) {  
                $errors[] = "Bitte geben Sie ein gültige eMail Adresse an";  
            }  
      
            if(empty($_POST['betreff'])){  
                $errors[] = "Bitte geben Sie einen Betreff an";  
            }  
    
    

    Dieses funktioniert auch, aber was ist wenn ich mehr als 10 / 20 Felder habe, der Code wird sau lang. Kann man diese prüfen etwas kurzer machen bzw. mit einer Funktion? Ich kenne mich da leider überhaupt nicht aus. Nur ich merke, es kommt sehr viel Schreibarbeit auf mich zu.

    Vielleicht gibt es ja eine Lösung.

    1. Hallo

      Dieses funktioniert auch, aber was ist wenn ich mehr als 10 / 20 Felder habe, der Code wird sau lang. Kann man diese prüfen etwas kurzer machen bzw. mit einer Funktion? Ich kenne mich da leider überhaupt nicht aus. Nur ich merke, es kommt sehr viel Schreibarbeit auf mich zu.

      Ja, wenn du die Prüfung explizit auf deinen konkreten Fall abstellst (was du anstreben solltest), wird für jedes Feld eine Prüfung fällig. Und ja, der Code wird mit zunehmender Anzahl der Felder länger und länger.

      Funktionen nehmen dir dann Arbeit ab, wenn sie wiederverwendbar sind, sprich, wenn du mehrere gleichartige Fälle hast, auf die du eine Funktion ansetzen kannst. Das wäre bei einer Formularvalidierung z.B. der Fall, wenn du mehrere Felder hast, die z.B. nur Zahlen oder nur Daten (als Plural von Datum (als Zeitangabe)) aufnehmen sollen. So könntest du mit einer Funktion alle Zahleneingaben und mit einer anderen alle Eingaben eines Datums prüfen. Eingaben, die nur Werte einer festgelegten Auswahl enthalten dürfen, kann man die Eingabe gegen ein Array mit den möglichen Werten prüfen (in_array).

      Das alles bedarf aber auch weiterhin eines Grundgerüsts, wie du es in deinem Posting notiert hast. Das darf auch in einer Funktion stehen, die von dem Formularskript aus aufgerufen wird. Ich persönlich finde es aber besser, dieses Gerüst im Formularskript zu notieren, weil ich da besser überblicke, welche Felder vorhanden sind und geprüft werden müssen. Zudem passt die Funktion unter Garantie auf ein weiteres, später eingeführtes Formular *nicht*. Damit ist sie nicht wiederverwendbar und, außer der eventuell notwendigen Übersicht wegen, überflüssig.

      Tschö, Auge

      --
      Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
      Terry Pratchett, "Wachen! Wachen!"
      ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
      Veranstaltungsdatenbank Vdb 0.3
    2. Tach!

      ich prüfe meine Felder wie folgt:
      Dieses funktioniert auch, aber was ist wenn ich mehr als 10 / 20 Felder habe, der Code wird sau lang. Kann man diese prüfen etwas kurzer machen bzw. mit einer Funktion?

      Manchmal ergibt sich eine Vereinfachung, weil man etwas zu umständlich gemacht hat. Das ist in deinem Fall aber grunsätzlich nicht gegeben. Die Werte müssen alle einzeln und mitunter mehreren Prüfungen unterzogen werden. Hier etwas vereinfachen zu wollen, schafft man nur bei gleichzeitiger Erhöhung der Komplexität an anderer Stelle. Die Frameworks haben üblicherweise solche Prüfungen an Bord und man muss nur noch sagen, welche Prüfung auf welches Feld angewendet werden soll. Das ist einfacher zu notieren, aber dafür hast du den Aufwand der Einarbeitung. Der lohnt sich erst, wenn du weitere Projekte machen muss, dann bist du mit denen schneller am Ziel. So zumindest im Idealfall.

      dedlfix.

    3. Mahlzeit!

      ich prüfe meine Felder wie folgt:

      $errors = array();

      if(empty($_POST['name'])) {
                  $errors[] = "Bitte geben Sie Ihren Namen an";
              }

      if(empty($_POST['email'])){
                  $errors[] = "Bitte geben sie Ihre eMail Adresse an";
              } elseif (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) == false) {
                  $errors[] = "Bitte geben Sie ein gültige eMail Adresse an";
              }

      if(empty($_POST['betreff'])){
                  $errors[] = "Bitte geben Sie einen Betreff an";
              }

      
      >   
      > Dieses funktioniert auch,  
        
      Gut, die Validate-Filter hast du ja schon mal gefunden. ;-)  
      Wichtig wären aber ggf. auch die [Sanitize-Filter](http://www.php.net/manual/de/filter.filters.sanitize.php).  
        
      Und du solltest eine sog. "mail header injection" oder auch "[E-Mail-Injection](http://de.wikipedia.org/wiki/E-Mail-Injection)" vermeiden.  
        
      
      > aber was ist wenn ich mehr als 10 / 20 Felder habe, der Code wird sau lang.  
        
      Hehe ..., ein Grund, warum man sich ggf. auf das Nötigste bei einem Kontaktformular beschränken sollte (muss es bspw. ein Eingabefeld für den Betreff geben?).  
        
      
      > Kann man diese prüfen etwas kurzer machen bzw. mit einer Funktion? Ich kenne mich da leider überhaupt nicht aus. Nur ich merke, es kommt sehr viel Schreibarbeit auf mich zu.  
        
      Ja, du kannst ja bspw. alle Eingaben durch eine Funktion jagen, die mögliche Injektionen "rausfiltert".  
        
      
      > Vielleicht gibt es ja eine Lösung.  
        
      Bestimmt sogar mehrere ...! ;-)  
        
        
      Gruß Gunther
      
  3. Ich teste mein Kontaktformular, alle eMails kommen an nur nach dem Abschicken bekomme ich eine „Notice: Undefined variable“ diese Variable sieht in meiner Seite so aus:

      
    $user_js_script .= "$('form[name=kontakt_user_form]').fadeOut();";  
    
    

    und aufgerufen wird diese so:

      
    if(isset($_POST['abschicken']) && empty($errors)){  
       echo $user_js_script;  
    }  
    
    

    was muss ich ändern, dass diese Notice verschwindet?

    1. Hi,

      Ich teste mein Kontaktformular, alle eMails kommen an nur nach dem Abschicken bekomme ich eine „Notice: Undefined variable“ diese Variable sieht in meiner Seite so aus:

      $user_js_script .= "$('form[name=kontakt_user_form]').fadeOut();";

      du versuchst, an den bisherigen Inhalt von $user_js_script noch einen String anzuhängen. Damit das geht, muss aber erstmal etwas da sein. Deswegen bekommst du hier die Notice, dass $user_js_script nicht definiert sei, gleichzeitig wird diese Variable als leerer String angelegt, und dann die Stringverkettung durchgeführt.

      Kann es sein, dass du nur eine direkte Zuweisung willst, und kein Anhängen?

      So long,
       Martin

      --
      Dem Philosoph ist nichts zu doof.
      Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
      1. Kann es sein, dass du nur eine direkte Zuweisung willst, und kein Anhängen?

        genau das wollte ich, da hat sich ein . eingeschlichen. Hab es so abgeändert:

        $user_js_script = "$('form[name=kontakt_user_form]').fadeOut();";

        Danke dir.