E-Mail Versand mit PHPMailer
PHP bietet die integrierte Funktion mail() an, um E-Mails zu verschicken.
Einfaches Beispiel:
PHP verschickt eine E-Mail an uli@lasona.de mit dem Betreff (Subject) E-Mail Versand mit PHP und der Nachricht (Body, Bodytext) ... ganz einfach mit der integrierten Funktion mail(). mail() unterstützt auch den Versand an weitere Empfänger in Kopie oder Blindkopie. Dazu muss der Header (vierter Parameter der mail() Funktion) entsprechend vorbereitet werden. Beispiel:
$Header .= "Content-type: text/html; charset=UTF-8\r\n";
$Header .= "From: noreply@lasona.de\r\n";
$Header .= "Cc: kopie@domain.de\r\n";
$Header .= "Bcc: blindkopie@domain.de\r\n";
$Header .= "Message-ID: <" . time() . "-" . md5("uli@lasona.de") . "@lasona.de>\r\n";
Im Internet gibt es viele Quellen mit weiteren Details und Beispiel PHP Code. Leider lassen sich mit dieser einfachen Mail Funktion nicht mehr alle Empfänger erreichen. Provider wie Apple (mit @icloud.com Adressen) oder GMX weisen diese E-Mails mit einer Fehlermeldung zurück, beispielsweise:
Remote-MTA: dns; mx02.mail.icloud.com
Diagnostic-Code: smtp; 554 5.7.1 [CS01] Message rejected due to local policy.
Please visit https://support.apple.com/en-us/HT204137
Auf der Suche nach einer Alternative kommt man an der Bibliothek PHPMailer nicht vorbei. Auch hier gibt es viele Quellen im Netz. Wer sich das erste Mal mit PHPMailer beschäftigt findet nicht sofort Antworten auf alle Fragen. Einige davon versuche ich hier zu beantworten.
Wie integriere ich PHPMailer in meine Umgebung?
Empfohlen wird, PHPMailer über dem Composer zu installieren. Wie funktioniert das?
Voraussetzung für den Einsatz von Composer ist der Shell Zugang über SSH zum Hosting Provider. Üblicherweise kann man im Kundencenter herausfinden, ob der SSH Zugang unterstützt wird (Beispiel von meinem Provider):

Für SSH wird ein entsprechender Client benötigt. Gute Erfahrungen habe ich mit dem kostenlosen Tool PuTTY gemacht (Version 0.83, Download).

Im Feld Host Name (or IP address) den entsprechenden Namen des FTP Servers eingeben (auch diese Information ist im Kundencenter des Providers zu finden). Stellt man dem Host name den Username vom Standard FTP User mit @-Zeichen getrennt voran und speichert die Konfiguration in PuTTY, muss bei der Verbindung nur noch das Passwort des FTP Users eingegben werden (also Format: ftpusername@hostnameftpzugang).

Nach der erfolgreichen Anmeldung mit SSH befindet man sich üblicherweise auf der höchsten Ebene des eigenen Webspace. Mit dem Befehl ls werden die vorhandenen Dateien und Verzeichnisse angezeigt:

In cgi-bin können CGI (Common Gateway Interface) Skripte hinterlegt werden, in htdocs liegen die HTML/PHP-Dateien der Webseite und in logfiles die Logdateien (soweit dies aktiviert ist). Zu Composer ist nichts zu finden. Hier hilft der erweiterte Befehl ls -a weiter, der auch die versteckten Dateien und Verzeichnisse anzeigt. Jetzt ist ein Verzeichnis .composer zu sehen. Mit cd .composer ist ein Wechsel in das Verzeichnis möglich.
Laut Beschreibung soll der Datei composer.json folgende Zeile hinzugefügt werden.
Alternativ folgenden Befehl ausführen:
Eine Datei composer.json finde ich nicht (das Verzeichnis .composer ist leer), also gebe ich obigen Befehl ein, erhalte aber eine Fehlermeldung:
file_put_contents(./composer.json): Failed to open stream: Permission denied
Ich erstelle eine Datei mit dem Namen composer.json und dem Inhalt "phpmailer/phpmailer": "^7.0.0" und kopiere diese mit FTP in meinen Webspace in das Verzeichnis .composer. Die erneute Ausführung des composer Befehls führt wieder zu einer Fehlermeldung, da der Composer eine JSON Struktur erwartet. Korrekt muss der Inhalt der Datei so aussehen:
"require": {
"phpmailer/phpmailer": "^7.0"
}
}
Jetzt läuft der Befehl
sauber durch und die Bibliothek PHPMailer steht anschließend zur Verfügung. Die Warnungen (Deprecation Notice = veraltet) können ignoriert werden.
In meinem Webspace lege ich in dem Unterverzeichnis test eine neue PHP Datei phpmailer.php mit folgendem Inhalt an:
<html>
<head><title>Sende E-Mail mit PHPMailer</title></head>
<body style="font-size: 12px;font-family:Verdana,Arial,Helvetica;font-weight:normal;">
<?php
include "vendor/autoload.php";
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
try {
$mail = new PHPMailer (true);
$mail->isSMTP();
$mail->SMTPAuth = true;
$mail->Host = "smtp.xxx.de"; // hier den SMTP Server eintragen
$mail->Port = "465"; // manchmal auch 687
$mail->Username = "xxx@xxx.de"; // E-Mail Adresse, die SMPT Mail verschickt
$mail->Password = "xxxxxxx"; // Passwort des SMTP Users
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->setFrom("xxx@xxx.de", "Name des Users");
$mail->addAddress("uli@lasona.de.de", "Uli Herzog");
$mail->addCC("xxx@icloud.com"); // optional: Kopie
$mail->addBCC("xxx@gmx.de"); // optional: Blindkopie
$mail->isHTML(true);
$mail->Subject = "Test E-Mail über PHPMailer";
$mail->Body = "Sollte funktionieren ...";
$mail->CharSet = "UTF-8";
$mail->Encoding = "base64";
$mail->send();
echo "... erfolgreich<br>";
} catch (Exception $e) {
echo "Mailer Error:<br>".$e->getMessage();
}
?>
Wenn ich jetzt die Seite mit www.meineDomain.de/test/phpmailer.php aufrufe, passiert - nichts!
Wo liegt der Fehler?
Leider wird keine Fehlermeldung angezeigt. Mehrmals überprüfe ich den Source Code und schaue mir im Internet andere Beispiele an. Letztendlich ist die Lösung einfach. Es hängt an der Zeile:
Alle Quellen im Internet geben diese Zeile so, machmal auch mit include_once oder require, aber immer mit vendor/autoload.php an. Beim Einbinden von Dateiein in PHP ist die Angabe vendor/ relativ. Beim Ausführen des Codes sucht PHP im Unterverzeichnis vendor. Dieses Verzeichnis existiert im test Ordner aber nicht - es befindet sich im versteckten Ordner .composer!
Am einfachsten lässt sich das Problem lösen, in dem man mit dem SSH Client in das Verzeichnis test wechselt und dort den Befehl:
nochmals ausführt. Damit wird im Verzeichnis test der Unterordner vendor inkl. weiteren Ordnern (composer, phpmailer) und Dateien angelegt. Anschließend funktioniert der Versand einer E-Mail mit obigem Source Code.
Ergänzung
Die Zeile:
besteht aus dem Namensraum (Namespace) und der Klasse (class). 3x PHPMailer sieht merkwürdig aus, ist aber korrekt.
Wenn kein SSH Zugang besteht und damit Composer nicht genutzt werden kann, kann die Bibliothek manuell eingebunden werden. Einfach auf Github die PHPMailer ZIP Datei herunterladen und extrahieren. Es werden nur drei Dateien benötigt, die sich im Ordner PHPMailer-master/src befinden:
PHPMailer.php
smtp.php
Diese Dateien in die Ordnerstruktur der eigenen Internetpräsenz kopieren. Das Verzeichnis ist beliebig, es muss nur im Source Code entsprechend korrekt referenziert werden. Ich habe auf der höchsten Ebene ein Verzeichnis lib und darin ein Unterverzeichnis PHPMailer angelegt.
Um die Mail Funktion nutzen zu können, müssen am Anfang des PHP Codes folgende Zeilen eingefügt werden:
use PHPMailer\PHPMailer\Exception;
require "lib/PHPMailer/Exception.php";
require "lib/PHPMailer/PHPMailer.php";
require "lib/PHPMailer/SMTP.php";
Weitere Details dazu sind auf Github zu finden.