Skip to main content

Kontaktformular 2 - Form Mailer

Schreibe einen einfachen Formmailer
Der Hintergrund

Das versenden einer E-Mail ist eine Aufgabe, die vom Postausgang übernommen wird. Die Auslieferung an einen Postausgangsserver kann in PHP mit verschiedenen Methoden erreicht werden:

  • Die Funktion mail()
  • Die Klasse PHPMailer
  • Die Klasse SwiftMailer
  • Eine externe API - z.B. SendGrid

Die Funktion Mail

Die Core-Funktion Mail ist bei weitem die einfachste Methode, um ein E-Mail zu senden. Sie gehört zur Grundausstattung von PHP und nutzt den lokal (auf dem aktuellen Server) konfigurierten Mailserver. Läuft dein Script gerade auf einem lokalen Testserver, kann ein E-mail nur gesendet werden, wenn dieser auch korrekt konfiguriert ist. Ausserdem gibt es verschiedene Gründe, wieso eine E-Mail, die so verschickt wird, beim Empfänger eher im Spamordner landet als mit den anderen Methoden. Spamfilter prüfen nämlich, woher eine E-Mail kommt, und ob die Herkunft vertrauenswürdig ist. Die Herkunft muss daher manuell korrekt definiert werden, unter anderem durch korrekte, vollständige Header-Angaben (eine E-Mail hat - wie jede andere Datei auch - neben dem Body auch einen Head, in dem technische Angaben zum Inhalt und des Typs enthalten sind, und bei der E-Mail auch über die Herkunft). Du kannst das Ziel, die E-Mail korrekt zu verschicken, auch mit mail() erreichen, es ist jedoch einiges an Wissen notwendig. Folgende Punkte sind zu beachten, wobei die meisten über die Header-Einträge gelöst werden. Beachte, dass der Header im Plain-Text Format geschrieben wird, und um mehrere Zeilen zu erhalten, hinter jeder Zeile Zeilenumbrüche angefügt werden müssen (\r\n)

  • Content-Format: im Head sollte auch enthalten sein, wie die E-Mail formatiert ist - du kannst HTML oder Plain Text verschicken, und je nach Content deiner Mail sollte dies hier angegeben sein.
    $headers = "MIME-Version: 1.0" . "\r\n";
    
    // Mitteilen, dass diese Nachricht als HTML gelesen werden muss
    $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n"; 
    So sieht der Content-Type für eine Plaintext nachricht ohne HTML Formatierung aus: 
    $headers = "MIME-Version: 1.0" . "\r\n";
    
    // Mitteilen, dass diese Nachricht als reiner, unformatierter Text gelesen werden muss
    $headers .= "Content-type:text/plain;charset=UTF-8" . "\r\n"; 
  • Absender: im Head muss enthalten sein, wie die E-Mail generiert wurde, denn sie wurde - technisch gesehen - nicht vom Postausgangsserver des Absenders verschickt, sondern von einem generischen Postausgangsserver. Es ist trotzdem wichtig, einen korrekten Absender anzugeben, da sonst ein generischer Standard-Absender verwendet wird, der noch viel weniger vertrauenswürdig wirkt. Der Absender sollte am besten ein bestehendes Mailkonto lautend auf die Domain sein, auf welcher dein Script ausgeführt wird (ist die Domain meineseite.com, so sollte es eine Adresse @meineseite.com sein).

    $headers .= "From: This email address is being protected from spambots. You need JavaScript enabled to view it." . "\r\n";
  • Antwort-Adresse: Es kann zwar praktisch sein, eine abweichende Antwortadresse anzugeben, allerdings kann dies von Spamfiltern auch als Versuch gewertet werden, zu verschleiern, dass die E-Mail nicht aus dem Postausgang der genannten Adresse stammt. Wenn du dies dennoch tun möchtest, kannst du eine bereinigte, validierte E-Mail Adresse (aus dem Formularfeld "E-Mail") einfügen:
    $headers .= "Reply-To: $input_email" . "\r\n";
    
  • X-Mailer: diese Angabe beschreibt das Programm / die Library, die die E-Mail generiert hat. Es ist nicht unbedingt notwendig, sie schafft jedoch Transparenz und somit Vertrauen. In unserem Fall wurde die E-Mail mit PHP erstellt und wir wollen dies auch ehrlich mitteilen. phpversion() erzeugt eine Art Signatur der PHP-Version:
    $headers .= 'X-Mailer: PHP/' . phpversion();


Weitere Gründe, wieso E-Mails mit mail() nicht ankommen: 

  • Fehlende Authentifizierung: Da E-Mails direkt über einen intern konfigurierten Prozess verschickt werden, findet keine Prüfung statt, ob das Script berechtigt ist, E-Mails zu senden. Es ist meist notwendig, den Server so zu konfigurieren, dass eine Prüfung stattfinden kann. Dies kann über SPF (Sender Policy Framework), DKIM (DomainKeys Identified Mail) und DMARC (Domain-based Message Authentication, Reporting & Conformance) erreicht werden - Signaturen und Informationen, die über die DNS Verwaltung (Domain Name System) eingetragen werden müssen auf deinem Server.
  • Reputation: Spamfilter überprüfen den Herkunftsserver (resp. dessen IP-Adresse) auf ihren guten Ruf. Wurde von dieser IP schon Spam versendet, ist deren Ruf zu schlecht, die E-Mail landet im Spam.

 

Die Klasse PHPMailer

PHPMailer ist kein Teil des Funktionsumfangs von PHP, sondern eine 3rd Party OOP Library, die einfache Funktionen zur Verfügung stellt, mit denen oben beschriebene Herausforderungen einfach gelöst werden. Mails können damit direkt an einen bestehenden Postausgangsserver verschickt werden, auf dem genau gleichen Weg, wie dies Dein Mailclient (Outlook, Mac Mail etc.) tut. Um PHPMailer nutzen zu können, muss dieser mit Composer installiert werden, was nicht auf allen Shared Hostings erlaubt ist, und somit einen zusätzlichen Schritt über deinen lokalen Testserver benötigt.

Vorteile

  • Du brauchst dich mit den meisten Stolpersteinen nicht auseinanderzusetzen
  • Header werden korrekt formatiert für dich
  • Der Postausgangsserver muss nicht am selben Ort liegen wie dein Script
  • Die Verbindung zum Postausgangsserver durchläuft einen Authentifizierungsvorgang (Du benötigst Server, Benutzernamen und Passwort, wie wenn du einen MailClient einrichtest) - somit hast du schon eine "Berechtigung zum Versand" von Mails 
  • Die Klasse ist - einmal eingerichtet - relativ einfach zu nutzen. Selbst E-Mails mit Attachments sind mit einer einzigen Zusatzzeile Code erstellt.
  • Du hast viel mehr Möglichkeiten, Fehler abzuhandeln als bei mail()

 

Die Klasse SwitftMailer

Wie PHPMailer ist dies auch eine 3rd-Party OOP Library, die mit Composer  installiert werden muss. Sie hat die gleichen Eigenschaften und Möglichkeiten wie PHPMailer, zeichnet sich jedoch in folgenden Punkten ab: 

  • bessere Performance - dies fällt jedoch nur bei grossen Mengen an E-Mails oder einem stark ausgelasteten Server (Hohe Nutzerzahl) ins Gewicht
  • Modularer und komplexer als PHPMailer

 

Externe API's - z.B. SendGrid

SendGrid ist ein Cloud-basierter E-Mail-Dienst, der eine API für den Versand von E-Mails bereitstellt. Du kannst die SendGrid-PHP-Bibliothek verwenden, um mit der API zu interagieren. Die SendGrid PHP-Library kann auch via Composer ins Projekt geladen werden. Nutzt du die Library, wird der Versand von SendGrid's hochverfügbaren Servern übernommen, mit welchen auch 20'000 oder 100'000 E-Mails schnell verschickt werden können (z.B. Newsletters). Es stehen ausserdem verschiedenste Analysetools zur Verfügung. Der Dienst ist jedoch kostenpflichtig und macht vor allem bei grossem Versandvolumen und bei Marketing-Zwecken Sinn.


So geht's

Zur Vorbereitung kannst du dir als erstes das kontaktformular.zip herunterladen und es in deinem lokalen Testserver installieren, oder das Tutorial Kontaktformular 1 durchspielen, in dem die Validierung beschrieben wird.

  1. Falls du die Validierung gemacht hast, und somit eine Statusvariable $hasErrors hast, kannst du nun in der entsprechenden Bedingung den Mailversand vorbereiten. Hast du noch keine Validierung gemacht, so erstelle dir eine Variable $hasErrors und setze ihren Wert auf false - dies simuliert die Situation, in der bei der Validierung kein Fehler entstanden ist. 
    $hasErrors = false;
    if( $hasErrors == false){
        // kein Fehler bei der Validierung - hier kommt der mailversand hin
    }
  2. Ist nun alles korrekt ($hasErrors ist false), kann ein Mail verschickt werden. Hierfür werden vier Parameter gebraucht: Empfänger, Betreff, Nachricht und Headers (in welchen du mindestens einen passenden Absender angeben solltest, damit die Nachricht nicht im Spam landet). Bereite daher zuerst die vier Variablen vor. 
  3. <?php 
    $empfaenger = This email address is being protected from spambots. You need JavaScript enabled to view it.'; // Die Adresse, an die das E-Mail geschickt werden soll
    $betreff = 'Kontaktanfrage von deiner Webseite'; // Ein bezeichnender Betreff
    $body = $message; // die Nachricht vom Formular
    
    // Mailheader im Plain Text Format
    $headers = "From: " . $email . "\r\n" .
      "Reply-To: " . $email . "\r\n" .
      "X-Mailer: PHP/" . phpversion();
    ?>
  4. Zum Schluss kannst du die Mail mit den vier parametern verschicken, und eine Erfolgsmeldung ausgeben, wenn dies funktioniert hat. Ob es funktioniert hat, erkennst du daran, ob die Funktion mail() true oder false zurückgibt. Es ist empfehlenswert, dies immer zu prüfen, damit dein Script drauf reagieren kann.
    $mailSent = mail($empfaenger, $betreff, $body, $headers); 
    
    // Success Message im HTML
    if($mailSent == true){
        echo '<div class="alert alert-success">Danke für deine Post!</div>';
    }

 

Mail mit PHPMailer versenden

Hast du PHPMailer eingerichtet auf deinem Testserver (siehe Hintergrundinfos), kannst du dieses Script etwas anpassen. Das folgende Codebeispiel soll den Unterschied sichtbar machen.

  1. Lade zuerst die Funktionalität von PHPMailer. Dies sollte am Anfang des Scripts geschehen, nicht innerhalb einer Bedingung.
    use PHPMailer\PHPMailer\PHPMailer; // Funktionalität von PHPMailer aktivieren
    use PHPMailer\PHPMailer\Exception; // Funktionalität von Exception fürs Fehlerhandling aktivieren
    
    require 'vendor/autoload.php'; // Autoload Datei enthält alle Pfade zu den benötigten Klassen
  2. Du brauchst auch hier eine Validierung und schlussendlich eine Abfrage, ob keine Fehler entstanden sind: 
    $hasErrors = false;
    if( $hasErrors == false){
        // kein Fehler bei der Validierung - hier kommt der mailversand hin
    }
  3. Instanziere dann PHPMailer in deiner Abfrage der $hasErrors Variable:
    $mail = new PHPMailer(true); // Objekt erzeugen aus der Klasse PHPMailer
  4. Konfiguriere dann den PHPMailer, so dass er sich mit deinem Mailkonto verbindet. Die Daten für das Mailkonto sowie die Authentifizierungseinstellungen können variieren und sind hier nur Beispiele:
    //Server settings
    $mail->SMTPDebug = 0;  // Debugging ausschalten
    $mail->isSMTP(); // SMTP als Transportmethode definieren
    $mail->Host = 'smtp.meineseite.com'; // Postausgangsserver
    $mail->SMTPAuth = true; // Authentifizierung aktivieren
    $mail->Username = This email address is being protected from spambots. You need JavaScript enabled to view it.'; // SMTP (Mailbox) username
    $mail->Password = 'test1234'; // SMTP (Mailbox) password
    $mail->SMTPSecure = 'tls'; // Verschlüsselung - hier "TLS"
    $mail->Port = 587; // TCP port für Postausgangsserver
    
  5. Absender und Empfänger definieren - bei einem Kontaktformular sollte dies ein festgelegter Wert sein.
    $mail->setFrom(This email address is being protected from spambots. You need JavaScript enabled to view it.', 'Mailer'); // Absender
    $mail->addAddress(This email address is being protected from spambots. You need JavaScript enabled to view it.', 'Terry Harker'); // Empfänger
  6. E-Mail Content festlegen: 
    // Content
    $mail->isHTML(false); // Legt fest, dass die Nachridcht als Plain-Text gelesen werden soll
    $mail->Subject = 'Kontaktaufnahme über meineseite.com'; // Betreff
    $mail->Body    = $input_message; // bereinigte und validierte E-Mail Nachricht aus dem Formularfeld "Nachricht"
  7. Nachricht senden inkl. Userfeedback
    $mailSent = $mail->send();
    if($mailSent == true){
        echo "Vielen Dank für deine Nachricht"; // Success Message
    }else{
        echo "Die E-Mail konnte nicht gesendet werden"; // Error message
    }

Wie du siehst, ist der Prozess etwas anders. Du musst etwas mehr konfigurieren, musst dich aber nicht um Formatierungen kümmern. Traust du dich, die OOP Library zu verwenden und gewöhnst dich an deren Schreibweise, wirst du bald merken, dass du so weniger Sorgen hast. Probiere ein Mail von deinem MAMP / XAMPP zu schicken - schaffst du, dass es ankommt?


Tips und Links

PHPMailer - FreeMail Accounts als SMTP nutzen

Wenn du noch kein Shared Hosting hast, kannst du auch eine FreeMail wie Gmail nutzen, um Mails mit PHPMailer. Hier findest du Anleitungen für GMail von Google und GMX.

Wird meine E-Mail als Spam eingestuft?

Die Anforderungen von Spamfiltern verändern sich im Laufe der Zeit, und somit auch die manuellen Massnahmen, die du treffen musst, ganz besonders, wenn dein Skript nicht nur Mails an dich schickt, sondern an Nutzer deiner Seite, deren Spamfilter du ja nicht kennst. Wenn du wissen willst, wie wahrscheinlich es ist, dass deine von PHP gesendete E-Mail im Spamfilter hängen bleibt, prüfe deine Mails am besten mit mail-tester.com. Dieser Dienst gibt dir ein Rating, genau wie der Spamfilter es macht, erklärt dir aber transparent, wie er zu diesem gekommen ist, und welche Massnahmen du ergreifen solltest. So lernst du die aktuellen Regeln von Spamfiltern kennen und hast am Schluss hoffentlich ein Mail, das jede Inbox erreicht.

Start

Formulardaten per Mail versenden

Verarbeite Daten aus einem Formular, um sie per E-Mail zu verschicken


Tags
Kategorie