Neben dem Zugriff auf eine Datenbank ist das Versenden von E-Mails mit die häufigste Anforderung an Webapplikationen. Wie Sie mit eZ Components E-Mails versenden und empfangen, zeigt Ihnen dieses Kapitel.
14 Mail
E-Mail war schon ein Dienst des Internets, bevor die ersten Internetseiten zu sehen waren. Kein Wunder also, dass eine der häufigsten Aufgaben bei der Entwicklung einer Webapplikation das Versenden von E-Mails ist. Ob lediglich die Daten aus einem Kontaktformular zugestellt werden wollen, der komplexe Geschäftsprozess die Benachrichtigung eines Akteurs verlangt oder der aktuelle Newsletter versendet werden soll, stets ist das Versenden von E-Mails im Spiel.
Aber auch das Empfangen von E-Mails kann innerhalb einer Webanwendung sinnvoll sein, wenn es auch seltener eine Anforderung ist. Die Reaktion auf nicht unzustellbare Newsletter, zum Beispiel die Deaktivierung des Empfängers, ist ein denkbarer Anwendungsfall.
Bei der Umsetzung beider Anforderungen unterstützt Sie die Mail-Komponente der eZ Components. Um Ihnen den Umgang mit der Komponente näherzubringen, werden wir in diesem Kapitel zwei neue Features für das Galileo-Press-Blog realisieren:
Zum einen wird die Blog-Software nun den Administrator über eingehende Kommentare informieren, was typisch für diese Art Anwendung ist. Das zweite Features ist nicht so häufig anzutreffen: Benutzer des GP-Blogs werden die Möglichkeit erhalten, per E-Mail Blog-Einträge zu verfassen. Eingehende E-Mails werden verarbeitet, angehängte Bilder und der HTML-Inhalt extrahiert und beides im GP-Blog abgelegt.
14.1 E-Mails senden 

Der Versand von simplen Text-E-Mails ist eine einfache Aufgabe in PHP, doch spätestens wenn es darum geht, HTML-E-Mails oder gar Anhänge zu versenden, gestaltet sich dies schon schwieriger. Wirklich problematisch wird es, wenn auf dem Server, auf dem eine Webanwendung laufen soll, die mail()-Funktion von PHP deaktiviert wurde oder kein Mail-Transport-Agent (MTA) installiert ist.
Der einzige Ausweg ist dann, direkt mit einem SMTP-Server zu kommunizieren, um den E-Mail-Versand zu realisieren. Letzteres kann auch eine Alternative zur PHP-internen Funktion sein, wenn diese zu langsam ist. Mehr dazu aber später.
In diesem Abschnitt werden Sie lediglich das rudimentäre Versenden einer E–Mail kennenlernen. HTML-E-Mails, Anhänge und alternative Versand- und Empfangsmethoden werden erst im nächsten Abschnitt besprochen. Zunächst soll aber die Architektur der Mail-Komponente beleuchtet werden, zumindest diejenigen Bereiche der Komponente, die bei der Realisierung des ersten GP-Blog-Features relevant sind.
14.1.1 Architektur 

Die zentrale Klasse der Mail-Komponente trägt den Namen ezcMail, und eine Instanz dieser Klasse repräsentiert eine einzelne E-Mail. Allerdings ist sie keine Basisklasse im eigentlichen Sinne, sondern die Klasse erbt von ezcMailPart, der generellen Basisklasse, um einen E-Mail-Bestandteil zu repräsentieren.
E-Mail-Bestandteile
ezcMailPart ist die Basis für alle spezialisierten E-Mail-Bestandteile. Eine Instanz von ezcMail stellt zum einen eine E-Mail dar, und kann zum anderen als Bestandteil einer E-Mail auftreten. Dies ist zum Beispiel der Fall, wenn Sie eine E-Mail als Anhang einer weiteren E-Mail verschicken.
Ein Objekt von ezcMail beinhaltet neben weiteren Daten einer E-Mail ein Attribut namens $body, das eine weitere Instanz von ezcMailPart enthält, die den Inhalt der E-Mail repräsentiert.
Sie erkennen bereits jetzt die modulare Struktur der Komponente. Selbst komplexe E-Mails lassen sich mit Hilfe der Mail-Part-Objekte aufbauen. Denn neben der Repräsentation der eigentlichen E-Mail durch ezcMail bringt die Komponente eine Reihe weiterer Mail-Parts mit sich, die als Körper einer E-Mail dienen können und weitere Verschachtelungen ermöglichen.
Der einfachste E-Mail-Bestandteil wird durch die Klasse ezcMailText repräsentiert, deren Objekte einfachen Textinhalt einer E-Mail darstellen. Mit einer Instanz von ezcMailText im $body-Attribut eines ezcMail-Objekts stellen Sie eine reine Text-E-Mail dar, wie Sie sie mit Sicherheit schon oft aus PHP heraus versendet haben.
Komplexere E-Mails, zum Beispiel mit Anhängen, HTML-Inhalt oder ähnlichem, bestehen nicht nur aus einem einzigen E-Mail-Bestandteil, sondern aus einer verschachtelten Struktur diese Objekte. Bei der Struktur orientiert sich die Mail-Komponente an den verschiedenen RFCs, die den Aufbau einer E-Mail beschreiben. Eine Part-Klasse entspricht jeweils dem MIME-Bestandteil einer E-Mail.
Wollen Sie zum Beispiel eine E-Mail erzeugen, die sowohl HTML- als auch alternativ anzuzeigenden Textinhalt enthalten soll, benötigen Sie dazu eine Instanz von ezcMailMultipartAlternative. Diese enthält wiederum zwei Objekte: Eines zur Darstellung des HTML-Inhalts und eines für die Textvariante. Das Multipart-Alternative-Objekt erzeugt den korrekten MIME-Code, der den Mail-Client des Empfängers anweist, beide Teile als Alternativen zu betrachten und die Darstellung anzuzeigen, die den Einstellungen des Benutzers entspricht.
Enthält die HTML-Darstellung Bilder, so ist das Objekt für diesen Bestandteil nicht bloß eine Instanz von ezcMailText, dessen Attribut $subType auf 'html' gesetzt wurde, sondern eine Instanz von ezcMailMultipartRelated. Objekte dieser Klasse enthalten weitere E-Mail-Bestandteile, die untereinander in Beziehung stehen. Der Hauptbestandteil, welcher in diesem Fall der HTML-Textteil ist, steht mit den Nebenbestandteilen, den eingebetteten Bildern, in Form von ezcMailFilePart-Objekten in Beziehung.
Sie werden weitere Details zu diesen E-Mail-Bestandteil-Klassen in Abschnitt 14.2, »E-Mails empfangen«, kennenlernen, wenn es darum geht, erhaltene E–Mails zu zerlegen und zu verarbeiten. Denn die Darstellung in Form eines ezcMail-Objekts wird in der Komponente nicht nur beim Erzeugen und Versenden neuer E-Mails verwendet, sondern auch beim Empfangen und Parsen.
Das E-Mail-Objekt
Neben den Körper-Bestandteilen einer E-Mail, die im $body-Attribut des Objekts residieren, trägt ein ezcMail-Objekt noch weitere Informationen. Jede E-Mail hat eine Absenderadresse, die sich im Attribut $from befindet. Inhalt dieses Attributs ist eine Instanz von ezcMailAddress, also die Repräsentation einer E-Mail-Adresse, welche sowohl die reine Adresse als auch potentiell den Namen des Absenders beinhaltet. Eine reine E-Mail-Adresse wie kore@php.net ist genauso darstellbar mit Hilfe von ezcMailAddress wie Tobias Schlitt <toby@php.net>.
Nicht nur das Attribut $from zur Speicherung der Absenderadresse, sondern auch die Attribute $to, $cc und $bcc enthalten Objekte dieses Typs. Im Unterschied zu $from allerdings nicht jeweils ein einzelnes, sondern ein Array mit beliebig vielen Elementen, da jeweils mehrere Empfänger einer E-Mail über diese Felder adressiert werden können.
Um die Empfängerlisten zu beeinflussen, können Sie den entsprechenden Attributen direkt ein Array von ezcMailAddress-Objekten zuweisen oder eine der Methoden addTo(), addCc() oder addBcc() verwenden, die jeweils eine ezcMailAddress-Instanz als Parameter erwarten und diese der entsprechenden Empfängerliste hinzufügen.
Weitere Bestandteile eines E-Mail-Objekts sind der Betreff, ein einfacher String im Attribut $subject, das bereits erwähnte $body-Attribut, welches die Instanz eines Erben von ezcMailPart enthält, sowie das Attribut $timestamp, mit dem Versand-Zeitstempel und der $messageId zur Speicherung der Nachrichten-ID.
Letztere sind allerdings nur lesend zugreifbare Virtual Properties. Beim Versenden einer E-Mail werden beide Daten vom versendenden Mail-Server gesetzt. Eine Änderung der Attribute bliebe also ohne Effekt und wird daher nicht unterstützt; beim Empfang einer E-Mail macht aber der lesende Zugriff Sinn. Schließlich existieren noch zwei weitere Attribute: $returnPath, mit dessen Hilfe der Return-Path-Header verwaltet wird, und $subjectCharset, in dem die Zeichencodierung der Betreff-Zeile gespeichert wird.
Kopfdaten
Neben den im letzten Abschnitt vorgestellten Attributen enthält ezcMail noch weitere Attribute, welche von ezcMailPart vererbt wurden. Bei diesen handelt es sich um Werte, die generisch für jeden E-Mail-Bestandteil relevant sind. So enthält jedes Objekt, dessen Klasse von ezcMailPart erbt, eine Instanz von ezcMailHeadersHolder, der internen Speicher-Klasse für Header-Informationen. Die Kopfdaten einer E-Mail können also von jedem Bestandteil eines ezcMail-Objekts beeinflusst werden. Beim Parsen von E-Mails werden die Header jeweils ihrem passenden E-Mail-Part zugeteilt. Der ezcMail-Bestandteil selbst generiert zum Beispiel die Header From, To, CC, BCC und Subject aus den entsprechenden Attributen.
Von außen haben Sie direkt nur lesenden Zugriff auf den Kopfdaten-Container eines E-Mail-Bestandteils; das Befüllen mit Informationen bleibt generell dem tragenden Objekt vorbehalten. Allerdings stellt ezcMailPart eine Methode namens setHeaders() bereit, der Sie ein Array mit zusätzlichen Header-Informationen übergeben können. Dabei ist jeweils der Schlüssel der Name des zu setzenden Headers, dem sein Inhalt zugeordnet wird.
Allerdings wird vor dem Versand einer E-Mail auf jedem E-Mail-Bestandteil die Methode generateHeaders() aufgerufen, welche das Objekt veranlasst, aus seinen internen Informationen alle bereitzustellenden Kopfdaten zu generieren. Haben Sie mittels setHeaders() ein Kopfdatum gesetzt, das der E-Mail-Bestandteil selbst generiert, so wird das Objekt Ihre geänderten Daten überschreiben.
Auch hier haben Sie eine Möglichkeit dem entgegenzuwirken: Die Methode appendExcludeHeaders() erwartet ein Array von Header-Namen, die bei der Generierung der Kopfdaten ignoriert werden sollen. Alle so angegebenen Kopfdaten werden also nicht mehr vom Bestandteilobjekt selbst generiert, sondern auf den von Ihnen gesetzten Werten belassen. Beachten Sie jedoch, dass die von einem Bestandteil generierten Header-Informationen wichtig für die korrekte Darstellung der E-Mail beim Empfänger sein können. Eine leichtfertige Änderung eines Datums kann beispielsweise zur Folge haben, dass Ihre E-Mail als invalide angesehen und daher nicht dargestellt wird.
Analog zu setHeaders() arbeitet setHeader(), wobei diese Methode statt eines Arrays von Kopfdaten den Namen des zu setzenden Headers als ersten Parameter und als zweiten den zu schreibenden Wert erwartet. Passend dazu gibt es die Methode getHeader(), welche nach dem ihr übergebenden Namen eines Headers sucht und dessen Inhalt zurückgibt.
Passend zur generateHeaders()-Methode, die einen E-Mail-Bestandteil anweist, die von ihm bereitgestellten Kopfdaten zu generieren und als einzelnen String zurückzugeben, existiert die Methode generateBody() zum Erzeugen des E–Mail-Bestandteil-Körpers. Auch diese Methode gibt den generierten Inhalt als String zurück. Sie ist jedoch nicht in ezcMailPart implementiert, sondern als abstrakt deklariert, sodass erweiterte Klassen zur Implementierung gezwungen werden.
Auf beide Methoden greift die generate()-Methode zu, die einen String zurückgibt, der sowohl die Kopfdaten als auch den Körperinhalt des E-Mail-Teils enthält.
Alle drei Methoden, die der Generierung des E-Mail-Textes aus der Objektstruktur dienen, können je nach Bedarf des Bestandteils überschrieben und angepasst werden, sodass zum Beispiel Kind-Bestandteile bei einem ezcMailMultipartAlternative-Objekt berücksichtigt werden. Eine Instanz dieser Klasse würde auf beiden Kind-Objekten, dem HTML- und dem Text-Bestandteil, die Methode generate() aufrufen, deren Ergebnis nach RFC-Vorgaben zusammensetzen und zurückgeben. So setzen sich die Aufrufe rekursiv fort und erzeugen schließlich eine komplette E-Mail aus der Baumstruktur ihrer Bestandteile.
Transporter
Nachdem Sie nun die Darstellung einer E-Mail als Objektstruktur kennengelernt haben, nähern wir uns nun dem Versand der E-Mail, welcher im nächsten Abschnitt am Beispiel des GP-Blogs erläutert wird. Da verschiedene Wege zum Versand einer E-Mail ins öffentliche Netz führen, bedient sich die Mail-Komponente an dieser Stelle des altbekannten Konzepts der Backend-Handler. Sie kennen bereits mehrere Beispiele für dieses Prinzip, wie die Configuration-Komponente, die Database-Komponente und das ImageConversion-Paket.
Die Mail-Komponente unterscheidet zwischen zwei Arten von Transport-Handlern (hier künftig oft Transporter genannt): Zum einen gibt es Handler-Klassen, die das Interface ezcMailTransport implementieren. Diese Transporter-Klassen implementieren eine Methode send(), die zum Versenden eines ezcMail-Objekts benutzt werden kann. Es handelt sich also im Gegensatz zur zweiten Art von Handler-Klassen um Sende-Transporter. Mit der zweiten Art von Transportern werden Sie in Abschnitt 14.2, »E-Mails empfangen«, in Berührung kommen, denn diese dienen dem Empfang von E-Mails. Zwei verschiedene Versand-Transporter werden bereits mit der Komponente mitgeliefert.
14.1.2 E-Mail-Versand 

Als Nächstes erfahren Sie, wie im GP-Blog die Funktionalität der Administrator-Benachrichtigung bei neuen Kommentaren implementiert wird.
Aktionen, die E-Mails betreffen, geben wir einen eigenen Action-Controller mit dem Namen gpBlogActionEmail. Diese Aktions-Klasse wird zwei Slots bereitstellen, wozu die Methoden mailComment() und checkBlogMail() implementiert werden. Die Letztere der beiden wird Thema in Abschnitt 14.2, »E-Mails empfangen«, sein; mailComment() wird auf den folgenden Seiten besprochen.
Der Einfachheit halber verbinden wir den ersten Slot mit dem Signal save_comment_success, welches bereits in Kapitel 10, »Benutzereingaben validieren«, kurz aufgetaucht ist. Es wird gesendet, um die Erfolgsbestätigung für einen neuen Kommentar anzuzeigen, was der Anforderung entspricht, den Administrator über neu eingetroffene Kommentare zu benachrichtigen. Da mehrere Slots nach einem Signal lauschen können und es in diesem Fall unbedeutend ist, ob zuerst die Webseite an den Benutzer des Blogs ausgeliefert oder die E-Mail an den Administrator gesendet wird, zeigt diese Vorgehensweise sehr gut die Möglichkeiten der modularen Erweiterung durch die Anwendungsarchitektur.
Im Verzeichnis stage12/classes/actions/ auf der Buch-CD finden Sie die Klasse in der Datei email.php. Die Präsentation der mailComment()-Methode haben wir an dieser Stelle in zwei Abschnitte aufgeteilt.
Konfiguration
Bevor Sie aber richtigen PHP-Code zu sehen bekommen, werden der GP-Blog-Konfiguration einige neue Einstellungen hinzugefügt. Die zu benachrichtigenden E-Mail-Adressen müssen bekannt sein, und die Absenderadresse wird ebenfalls konfigurierbar gemacht. Da später in diesem Kapitel weitere Einstellungen folgen werden, wird eine neue Konfigurationsdatei namens email.ini im Verzeichnis config/ erzeugt.
Der bisherige Inhalt diese Datei sieht wie folgt aus:
[send] from=gpblog@example.com to[]=toby@php.net to[]=kore@php.net
Listing 14.1 Einstellungen in der Datei email.ini
In den folgenden Abschnitten kann also auf den Wert der Einstellung from zugegriffen werden, um den Absender der zu versendenden E-Mail zu bestimmen, sowie auf das Array der Einstellung to, welches die Adressen der Benachrichtigungsempfänger enthält. Näheres über den Zugriff auf Konfigurationsdateien entnehmen Sie bitte Kapitel 5, »Konfiguration«.
Eine E-Mail erstellen
Der erste Teil der mailComment()-Methode beschäftigt sich mit der Vorbereitung der eigentlichen Arbeit. Der benötigten Parameter, also die ID des frisch gespeicherten Kommentarobjekts, muss aus der URL extrahiert und die Modell-Objekte, also der Kommentar und der dazu gehörende Blog-Eintrag, müssen geladen werden. Wir blenden den ersten Teil der Methode an dieser Stelle aus. Sie können den kompletten Sourcecode auf Ihrer Buch-CD einsehen.
Die Erstellung eines neuen ezcMail-Objekts ist Thema des zweiten Teils der Methode, den Sie im Folgenden sehen:
public static function mailComment( ezcUrl $url,
ezcUrlConfiguration $config )
{
// ... loading ...
$mail = new ezcMailComposer();
$mail->subject = "[GP-Blog] New comment by
'{$comment->email}'";
$mail->plainText = <<<EOT
Hello {$cfg->getSetting( 'site', 'general', 'name' )},
{$comment->email} posted a new comment to your blog entry
'{$entry->title}':
{$comment->body}
Sincerly,
your GP Blog.
EOT;
$mail->from = new ezcMailAddress(
$cfg->getSetting( 'email', 'send', 'from' )
);
foreach ( $cfg->getSetting( 'email', 'send', 'to' ) as $to )
{
$mail->addTo( new ezcMailAddress( $to ) );
}
$mail->build();
// ...
}Listing 14.2 Eine neue E-Mail erstellen
Nehmen Sie für dieses Beispiel an, in der Variablen $cfg befände sich das globale Konfigurationsobjekt, wie Sie es aus Kapitel 5, »Konfiguration«, kennen, um den Zugriff auf die im letzten Abschnitt gesehenen Einstellungen zu realisieren. Des Weiteren ist $comment der abgegebene Kommentar in Form seines Modell-Objekts, und in $entry befindet sich das dazu passende Eintragsobjekt.
Zur Erstellung einer einfachen Text-E-Mail wird die Klasse ezcMailComposer verwendet. Sie erbt von ezcMail und erzeugt eine einfache E-Mail. Zwar kennen Sie sich nun auch mit der Architektur eines reinen ezcMail-Objekts aus und könnten die zu sendende E-Mail auch aus ihren einzelnen Bestandteilen zusammensetzen. Für viele Anwendungsfälle ist aber der Weg durch die Composer-Klasse einfacher und komfortabler. Den Umgang mit komplexeren E-Mail-Objekten werden Sie in Abschnitt 14.2, »E-Mails empfangen«, kennenlernen.
ezcMailComposer bildet einen Wrapper für die Erzeugung einer komplexen Objektstruktur aus ezcMailPart-Klassen. Die Klasse ermöglicht das komfortable Erzeugen von einfachen Text-E-Mails sowie HTML-E-Mails und E-Mails mit Anhängen. Alle weiteren, noch komplexeren Formate benötigen detailliertere Kenntnisse über die Struktur von E-Mails.
Im gezeigten Code wird zunächst das $subject-Attribut des Composers gesetzt, welches dieser von ezcMail geerbt hat und das Sie bereits aus Abschnitt 14.1.1, »Architektur«, kennen. Direkt im Anschluss wird das Attribut $plainText mit dem Körper der E-Mail gefüllt. Wollten Sie eine HTML-E-Mail erzeugen, wäre das Attribut $htmlText das Ziel für den Inhalt gewesen.
Das Composer-Objekt reagiert später korrekt auf alle möglichen Varianten und erzeugt wahlweise einen reinen Text- oder HTML-Bestandteil als Körper der E–Mail sowie eine Instanz von ezcMailMultipartAlternative für den Fall, dass Sie beide Attribute setzen. In letzterem Fall entscheidet der empfangene E-Mail-Client selbst, ob die HTML- oder die reine Textvariante angezeigt werden soll.
Die Zuweisung des Textkörpers erstreckt sich über mehrere Zeilen, weshalb Heredoc-Syntax [http://php.net/manualb/en/language.types.string.php#language.types.string.syntax.heredoc ] verwendet wird. Innerhalb des Textes kommen lediglich die beiden Modell-Objekte und das Konfigurationsobjekt zum Einsatz, um einige Werte einzufügen. Sowohl der Kommentar als auch der Titel des Eintrags werden im Text verwendet, neben dem Namen des Blog-Besitzers als Anrede, der aus der zentralen Konfiguration geladen wird.
Die nachfolgende Zuweisung des Attributs $from und das Hinzufügen von Empfängeradressen mittels addTo() kennen Sie ebenfalls bereits aus dem vorangegangen Architekturabschnitt, das Composer-Objekt erbt beide von ezcMail.
Das letzte Kommando im dargestellten Codeabschnitt ist wiederum neu gegenüber ezcMail und bewirkt, dass die erweiterten Daten des Composers in entsprechende Strukturen eines ezcMail-Objekts verpackt werden. Für dieses Beispiel bedeutet dies, dass der im $plainText-Attribut des Composers enthaltene Textinhalt in einen neuen ezcMailText-Bestandteil eingepackt und als $body-Attribut der E-Mail gesetzt wird. Danach verhält sich der Composer, als sei er ein manuell erzeugtes ezcMail-Objekt. Er ist nun versandbereit.
Im gezeigten Fall aus dem GP-Blog hat die Verwendung der ezcMailComposer-Klasse an Stelle von ezcMail direkt keinen nennenswerten Vorteil erbracht, denn lediglich die Erzeugung eines neuen ezcMailText-Objekts musste nicht selbst programmiert werden. Dafür ist der Aufruf der build()-Methode hinzugekommen, was beim direkten Erstellen der E-Mail-Struktur mittels ezcMail nicht notwendig gewesen wäre.
Doch schon das einfache Setzen von HTML-Inhalt und Textinhalt für den Körper wäre allein mit der ezcMail-Klasse aufwendiger geworden. Neben den zwei ezcMailText-Instanzen für beide Texte benötigen Sie noch ein Objekt der Klasse ezcMailMultipartAlternative. Soll die E-Mail auch noch Anhänge enthalten, eine Rechnung im PDF-Format zum Beispiel, reduziert der ezcMailComposer den notwendigen Programmieraufwand erheblich.
Die E-Mail versenden
Das Versenden der E-Mail gestaltet sich im GP-Blog wesentlich kürzer als der erste Teil der mailComment()-Methode. Lediglich zwei Codezeilen sind notwendig, um die im letzten Abschnitt erstellte E-Mail zu versenden.
// ... built mail ...
$transport = new ezcMailMtaTransport();
$transport->send( $mail );
}Listing 14.3 Der E-Mail-Versand
Die Klasse ezcMailMtaTransport implementiert das Interface ezcMailTransport und kann daher zum Versenden von ezcMail-Objekten benutzt werden. Mit MTA-Transport wird die Verwendung der PHP-internen mail()-Funktion als Backend bezeichnet. Das so erzeugte Transport-Objekt ist die einfachere von zwei verfügbaren Varianten in der Mail-Komponente. Lediglich dem hier gezeigten parameterfreiem Konstruktor und der Methode send() werden keine weiteren Funktionalitäten zur Verfügung gestellt.
Der ebenfalls mit der Mail-Komponente auf Ihrer Festplatte angekommene alternative Transporter für den Versand von E-Mails lautet ezcMailSmtpTransport. Wie der Name bereits sagt, verwendet diese Handler-Klasse als Backend einen SMTP-Server und verbindet sich mit Hilfe der PHP-internen Socket-Funktionen direkt zu diesem. [http://php.net/sockets ] Dies kann nützlich sein, falls Ihr Hosting-Provider die PHP-Funktion mail() deaktiviert oder keinen MTA installiert hat, was ab und zu als Maßnahme gegen Spam-Versender der Fall ist.
Der zweite Anwendungsfall ist aber wesentlich bedeutender, denn der Versand durch einen SMTP-Server kann die Performance der Applikation bei hohem E–Mail-Aufkommen stark beeinflussen. Rufen Sie in PHP direkt die mail()-Funktion auf, so startet der PHP-Interpreter im Standardfall – ähnlich wie ein Shell-Aufruf – den lokalen MTA und übergibt diesem Programm die Verantwortung zum Versenden der E-Mail. Für die Maschine, auf der Ihre Applikation läuft, bedeutet dies eine Zeitverzögerung durch das Initialisieren eines neuen Kontextes, in dem der MTA-Prozess läuft, sowie einige Speicherkopien für den E-Mail-Inhalt. Erzeugen Sie sehr viele E-Mails, werden Sie diese Last irgendwann an einen weiteren Server auslagern wollen, der sich gezielt um den E-Mail-Versand kümmert, was mit einem lokalen MTA-Aufruf nicht ohne Weiteres möglich ist.
Arbeiten Sie mit einem Windows-Rechner oder haben Sie lokalen Zugriff auf die Datei php.ini, stellt dies aber kein Problem dar. Lediglich eine Einstellung in dieser Datei veranlasst den PHP-Interpreter, statt des lokalen MTA einen SMTP-Server zum Versand zu verwenden. Alle damit entstehenden Skalierungsoptionen bis hin zum Aufbau eines Load-Balancing-Systems über mehrere E-Mail-Server stehen Ihnen damit offen. Auf Windows-Systemen ist es äußerst selten, dass ein lokaler MTA installiert ist, weshalb hier zumeist von vornherein ein weiterer SMTP-Server für die mail()-Funktion verwendet wird.
Trotzdem bietet Ihnen der SMTP-Transporter einen weiteren Vorteil gegenüber der mail()-Funktion. Denn ein Flaschenhals bei deren Verwendung kann sein, dass die PHP-Engine nicht weiß, ob Sie nach einem Aufruf der Funktion noch weitere E-Mails versenden wollen. Dadurch wird Zeit mit wiederholten Verbindungsauf- und -abbauten vergeudet, sollten Sie entsprechend viele E-Mails auf einen Schlag versenden wollen. Der Aufruf der Methode keepConnection() vor dem ersten Versand veranlasst das Transporter-Objekt, die Verbindung zum SMTP-Server nicht sofort nach der Übermittlung der E-Mail zu schließen, sondern im Hintergrund offen zu halten. Beim nächsten Aufruf wird diese Verbindung dann erneut verwendet, was bereits einen Verbindungsabbau und den nachfolgenden Verbindungsaufbau erspart. Der nachfolgende Code zeigt Ihnen, wie der letzte Codeschnipsel zu ersetzen ist, um einen SMTP-Server für den Versand zu benutzen:
// ... built mail...
$transport = new ezcMailSmtpTransport(
'smtp.example.com',
'my_user_name',
'my_password'
);
$transport->send( $mail );
}Listing 14.4 Der SMTP-Transporter im Einsatz
Wie Sie sehen, erwartet der Konstruktor des SMTP-Transporters mindestens einen Parameter, den Hostnamen des SMTP-Servers, zu dem eine Verbindung aufgenommen werden soll. Sie sehen im Beispiel, wie Sie Benutzerdaten für die Verbindung mit angeben. Der Konstruktor der Klasse unterstützt noch zwei weitere, optionale Parameter, nämlich die Port-Nummer auf dem Server, der kontaktiert werden soll, und ein Array mit weiteren Optionen.
Dieses Array wird intern in eine Instanz von ezcMailSmtpTransportOptions umgewandelt, wie Sie es bereits von mehreren Komponenten kennen. Die unterstützten Optionen sind der $connectionType (Verbindungstyp) und $preferredAuthMethod. Der Verbindungstyp wird über eine Klassen-Konstante festgelegt; der Standardwert ist ezcMailSmtpTransport::CONNECTION_PLAIN, was einer unverschlüsselten Verbindung entspricht. Weitere Möglichkeiten sind zum Beispiel CONNECTION_SSL, CONNECTION_SSLV2, CONNECTION_SSL3 und CONNECTION_TLS. Die ersten drei stehen für jeweils eine Art von SSL-Verschlüsselung, die letzte Konstante bestimmt eine TLS-gesicherte Verbindung. Viele SMTP-Server unterstützen nur einen dieser Mechanismen, weshalb Sie zunächst prüfen sollten, für welches Sicherungsverfahren Sie sich entscheiden. E-Mails über eine ungesicherte Verbindung zu versenden, ist nicht anzuraten.
Mit Hilfe der Option $preferredAuthMethod bestimmen Sie die bevorzugte Methode, mit der sich der Transporter am SMTP-Server anmelden soll. Standardmäßig testet die Klasse von sich aus, welche Authentifizierungsmechanismen der Server bereitstellt und wählt die erste passende Möglichkeit aus. Setzen Sie die Option $preferredAuthMethod auf einen konstanten Wert aus ezcMailSmtpTransport::AUTH_*, zum Beispiel auf AUTH_CRAM_MD5, so wird zunächst versucht, diese Methode zu verwenden. Erst wenn diese nicht vom Server unterstützt wird, wird eine andere gewählt.




Ihre Meinung






