E-Mails senden
Möchten Sie E-Mails versenden, zum Beispiel Newsletter oder Bestellbestätigungen? Das Nette Framework bietet die notwendigen Werkzeuge mit einer sehr angenehmen API. Wir zeigen Ihnen:
- wie man eine E-Mail inklusive Anhängen erstellt
- wie man sie versendet
- wie man E-Mails und Templates verbindet
Installation
Sie können die Bibliothek mit dem Werkzeug Composer herunterladen und installieren:
composer require nette/mail
E-Mail erstellen
Eine E-Mail ist ein Objekt der Klasse Nette\Mail\Message. Wir erstellen sie zum Beispiel so:
$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
->addTo('petr@example.com')
->addTo('jirka@example.com')
->setSubject('Bestellbestätigung')
->setBody("Guten Tag,\nIhre Bestellung wurde angenommen.");
Alle eingegebenen Parameter müssen in UTF-8 sein.
Neben der Angabe des Empfängers mit der Methode addTo()
kann auch ein Kopie-Empfänger addCc()
oder
ein Blindkopie-Empfänger addBcc()
angegeben werden. In all diesen Methoden, einschließlich setFrom()
,
können wir den Adressaten auf drei Arten schreiben:
$mail->setFrom('franta@example.com');
$mail->setFrom('franta@example.com', 'Franta');
$mail->setFrom('Franta <franta@example.com>');
Der in HTML geschriebene E-Mail-Textkörper wird mit der Methode setHtmlBody()
übergeben:
$mail->setHtmlBody('<p>Guten Tag,</p><p>Ihre Bestellung wurde angenommen.</p>');
Sie müssen keine Textalternative erstellen, Nette generiert sie automatisch für Sie. Und wenn die E-Mail keinen Betreff hat,
versucht Nette, ihn aus dem <title>
-Element zu übernehmen.
Bilder können auch außergewöhnlich einfach in den HTML-Textkörper eingefügt werden. Es genügt, als zweiten Parameter den Pfad anzugeben, wo sich die Bilder physisch befinden, und Nette fügt sie automatisch in die E-Mail ein:
// fügt automatisch /path/to/images/background.gif zur E-Mail hinzu
$mail->setHtmlBody(
'<b>Hello</b> <img src="background.gif">',
'/path/to/images',
);
Der Algorithmus, der Bilder einfügt, sucht nach diesen Mustern: <img src=...>
,
<body background=...>
, url(...)
innerhalb des HTML-Attributs style
und der speziellen
Syntax [[...]]
.
Kann das Senden von E-Mails noch einfacher sein?
Eine E-Mail ist wie eine Postkarte. Senden Sie niemals Passwörter oder andere Zugangsdaten per E-Mail.
Anhänge
Natürlich können Anhänge in die E-Mail eingefügt werden. Dazu dient die Methode
addAttachment(string $file, ?string $content = null, ?string $contentType = null)
.
// fügt die Datei /path/to/example.zip unter dem Namen example.zip in die E-Mail ein
$mail->addAttachment('/path/to/example.zip');
// fügt die Datei /path/to/example.zip mit dem Namen info.zip in die E-Mail ein
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));
// fügt die Datei example.txt mit dem Inhalt "Hello John!" in die E-Mail ein
$mail->addAttachment('example.txt', 'Hello John!');
Templates
Wenn Sie HTML-E-Mails senden, bietet es sich an, diese im Templating-System Latte zu schreiben. Wie geht das?
$latte = new Latte\Engine;
$params = [
'orderId' => 123,
];
$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
->addTo('petr@example.com')
->setHtmlBody(
$latte->renderToString('/path/to/email.latte', $params),
'/path/to/images',
);
Die Datei email.latte
:
<html>
<head>
<meta charset="utf-8">
<title>Bestellbestätigung</title>
<style>
body {
background: url("background.png")
}
</style>
</head>
<body>
<p>Guten Tag,</p>
<p>Ihre Bestellung Nummer {$orderId} wurde angenommen.</p>
</body>
</html>
Nette fügt automatisch alle Bilder ein, setzt den Betreff gemäß dem <title>
-Element und generiert eine
Textalternative zum HTML.
Verwendung in Nette Application
Wenn Sie E-Mails zusammen mit Nette Application, d.h. mit Presentern, verwenden, möchten Sie möglicherweise Links in
Templates mit dem Attribut n:href
oder dem Tag {link}
erstellen. Latte kennt diese standardmäßig
nicht, aber es ist sehr einfach, sie hinzuzufügen. Das Erstellen von Links übernimmt das Objekt
Nette\Application\LinkGenerator
, das Sie erhalten, indem Sie es sich mittels Dependency Injection übergeben lassen:
use Nette;
class MailSender
{
public function __construct(
private Nette\Application\LinkGenerator $linkGenerator,
private Nette\Bridges\ApplicationLatte\TemplateFactory $templateFactory,
) {
}
private function createTemplate(): Nette\Application\UI\Template
{
$template = $this->templateFactory->createTemplate();
$template->getLatte()->addProvider('uiControl', $this->linkGenerator);
return $template;
}
public function createEmail(): Nette\Mail\Message
{
$template = $this->createTemplate();
$html = $template->renderToString('/path/to/email.latte', $params);
$mail = new Nette\Mail\Message;
$mail->setHtmlBody($html);
// ...
return $mail;
}
}
Im Template erstellen wir dann Links wie gewohnt. Alle über LinkGenerator erstellten Links sind absolut.
<a n:href="Presenter:action">Link</a>
E-Mail senden
Mailer ist eine Klasse, die für das Senden von E-Mails zuständig ist. Sie implementiert die Schnittstelle Nette\Mail\Mailer und es stehen mehrere vorbereitete Mailer zur Verfügung, die wir vorstellen werden.
Das Framework fügt automatisch einen Dienst vom Typ Nette\Mail\Mailer
zum DI-Container hinzu, der auf Basis der
Konfiguration erstellt wird und den Sie erhalten, indem Sie ihn sich mittels Dependency Injection übergeben lassen.
SendmailMailer
Der Standard-Mailer ist SendmailMailer, der die PHP-Funktion mail verwendet. Anwendungsbeispiel:
$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);
Wenn Sie returnPath
setzen möchten und Ihr Server ihn immer überschreibt, verwenden Sie
$mailer->commandArgs = '-fMeine@email.de'
.
SmtpMailer
Zum Senden von E-Mails über einen SMTP-Server dient SmtpMailer
.
$mailer = new Nette\Mail\SmtpMailer(
host: 'smtp.gmail.com',
username: 'franta@gmail.com',
password: '*****',
encryption: 'ssl',
);
$mailer->send($mail);
Dem Konstruktor können diese weiteren Parameter übergeben werden:
port
– wenn nicht gesetzt, wird der Standardport 25 oder 465 fürssl
verwendettimeout
– Timeout für die SMTP-Verbindungpersistent
– persistente Verbindung verwendenclientHost
– Einstellung des Host-Headers des ClientsstreamOptions
– ermöglicht die Einstellung von SSL context options für die Verbindung
FallbackMailer
Sendet E-Mails nicht direkt, sondern vermittelt den Versand über eine Reihe von Mailern. Wenn ein Mailer fehlschlägt, wiederholt er den Versuch mit dem nächsten. Wenn auch der letzte fehlschlägt, beginnt er wieder beim ersten.
$mailer = new Nette\Mail\FallbackMailer([
$smtpMailer,
$backupSmtpMailer,
$sendmailMailer,
]);
$mailer->send($mail);
Als weitere Parameter im Konstruktor können wir die Anzahl der Wiederholungen und die Wartezeit in Millisekunden angeben.
DKIM
DKIM (DomainKeys Identified Mail) ist eine Technologie zur Erhöhung der Vertrauenswürdigkeit von E-Mails, die auch zur Erkennung gefälschter Nachrichten beiträgt. Die gesendete Nachricht wird mit dem privaten Schlüssel der Absenderdomäne signiert und diese Signatur wird im Header der E-Mail gespeichert. Der Empfängerserver vergleicht diese Signatur mit dem öffentlichen Schlüssel, der in den DNS-Einträgen der Domäne gespeichert ist. Wenn die Signatur übereinstimmt, ist nachgewiesen, dass die E-Mail tatsächlich von der Absenderdomäne stammt und während der Übertragung nicht verändert wurde.
Sie können das Signieren von E-Mails für den Mailer direkt in der Konfiguration einstellen. Wenn Sie keine Dependency Injection verwenden, wird es auf diese Weise verwendet:
$signer = new Nette\Mail\DkimSigner(
domain: 'nette.org',
selector: 'dkim',
privateKey: file_get_contents('../dkim/dkim.key'),
passPhrase: '****',
);
$mailer = new Nette\Mail\SendmailMailer; // oder SmtpMailer
$mailer->setSigner($signer);
$mailer->send($mail);
Konfiguration
Übersicht über die Konfigurationsoptionen für Nette Mail. Wenn Sie nicht das gesamte Framework, sondern nur diese Bibliothek verwenden, lesen Sie, wie die Konfiguration geladen wird.
Zum Senden von E-Mails wird standardmäßig der Mailer Nette\Mail\SendmailMailer
verwendet, der nicht weiter
konfiguriert wird. Wir können ihn jedoch auf Nette\Mail\SmtpMailer
umschalten:
mail:
# verwendet SmtpMailer
smtp: true # (bool) Standard ist false
host: ... # (string)
port: ... # (int)
username: ... # (string)
password: ... # (string)
timeout: ... # (int)
encryption: ... # (ssl|tls|null) Standard ist null (hat den Alias 'secure')
clientHost: ... # (string) Standard ist $_SERVER['HTTP_HOST']
persistent: ... # (bool) Standard ist false
# Kontext für die Verbindung zum SMTP-Server, Standard ist stream_context_get_default()
context:
ssl: # Übersicht der Optionen auf https://www.php.net/manual/en/context.ssl.php
allow_self_signed: ...
...
http: # Übersicht der Optionen auf https://www.php.net/manual/en/context.http.php
header: ...
...
Mit der Option context › ssl › verify_peer: false
kann die Überprüfung von SSL-Zertifikaten deaktiviert
werden. Wir raten dringend davon ab, dies zu tun, da die Anwendung dadurch anfällig wird. Fügen Sie stattdessen Zertifikate zum Trust Store hinzu.
Zur Erhöhung der Vertrauenswürdigkeit können wir E-Mails mit der DKIM-Technologie signieren:
mail:
dkim:
domain: myweb.com
selector: lovenette
privateKey: %appDir%/cert/dkim.priv
passPhrase: ...
DI-Dienste
Diese Dienste werden dem DI-Container hinzugefügt:
Name | Typ | Beschreibung |
---|---|---|
mail.mailer |
Nette\Mail\Mailer | Klasse zum Senden von E-Mails |
mail.signer |
Nette\Mail\Signer | DKIM-Signierung |