Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Mail

Senden von
E-Mails

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ür ssl verwendet
  • timeout – Timeout für die SMTP-Verbindung
  • persistent – persistente Verbindung verwenden
  • clientHost – Einstellung des Host-Headers des Clients
  • streamOptions – 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
Version: 4.0