UTF-8 Mails mit PHP

Vorwissen

Der Leser (oder die Leserin) solle bereits über Mailversand mit PHP Bescheid wissen. Sollte das nicht der Fall sein, ist wohl eher die PHP-Faq geeignet: 15. Mail lesen und schreiben

UTF-8 in Header Angaben

Subject

Zum Einstieg gleich mal ein Beispiel:

Subject: =?utf-8?b?VW1sYXV0czogw7zDtsOkw58kJSY=?=
		

Dieser Betreff wird dargestellt als `Umlauts: üöäß$%&'

Die Umlaute selbst dürfen nicht in die Header geschrieben werden, da alle Header 7bit codiert sein müssen - und das trifft nur auf ASCII Zeichen zu.

Daher müssen die Umlaute (8bit kodierte Zeichen) anders kodiert werden. Im obeigen Beispiel wird als Kodierung base64 verwendet. Die Kodierung wird zwischen dem 2. und dem 3. Fragezeichen angegeben (`b' steht für base64).

Zwischen 3. umd 4. Fragezeichen steht der base64 kodierte Text. In PHP wird dieser folgendermaßen erstellt:

base64_encode( "Umlauts: üöäß$%&" );
		

From

Im wesentlichen ist der From Header gleich aufgebaut wie der Subject Header, allerdings wird hier die E-Mail Adresse nicht kodiert. Der Header könnte also in etwa so aussehen:

From: =?utf-8?b?Q2hyaXN0aWFuIFNhZ23DvGxsZXI=?= <christian@example.net>
		

Angezeigt wird dies in etwa so:

From: Christian Sagmüller <christian@sagmueller.net>
		

Da die E-Mail Adresse nur ASCII Zeichen enthält, muss sie auch nicht gesondert behandelt werden.

Prinzipiell können kodierte und nicht-kodierte Bereiche beliebig kombiniert werden (zB könnte im obigen Beispiel nur `Sagmüller' kodiert werden, da `Chirstian' nur aus ASCII Zeichen besteht, allerdings bringt dieser zusätzliche Aufwand nicht sonderlich viel.

Weiterführende Informationen

Weitere Beispiele und Informationen sind im RFC 2047 zu finden.

UTF-8 im Body

Zusätzliche Header-Informationen

Content-Type

Da sich PHP EntwicklerInnen überlicherweise mit (X)HTML und HTTP auskennen (sollten) ist dieser Header eigentlich nichts Neues, da er genau so aufgebaut ist, wie der Content-Type Header in HTTP:

Content-Type: text/plain; charset=utf-8
		

Content-Transfer-Encoding

Allerdings reicht das Setzen des Content-Type nicht aus. Das SMTP Protokoll geht davon aus, dass die Daten 7bit (US-ASCII) kodiert übertragen werden. Bei UTF-8 Ist das allerdings nicht der Fall. Hier kommt der Header `Content-Transfer-Encoding' ins Spiel:

Content-Transfer-Encoding: 8bit
		

Mit diesem Encoding könnte nun der Body alle nicht ASCII Zeichen enthalten. Allerdings gibt es hier Probleme mit dem SMTP Protokoll (RFC 821) und der SMTP Server muss zusätzlich SMTP Service Extension for 8bit-MIMEtransport unterstützen.

Um hier keine Probleme mit alten Mailservern zu bekommen kann auch der Body base64 kodiert werden. Folgender Header zeigt diese Kodierung an:

Content-Transfer-Encoding: base64
		

Body

In diesem Fall ist der komplette Body base64 kodiertzu senden. Daher wird das =?[charset]?[encoding]?[encoded text]?= Muster, wie es bei den Headern verwendet wird überflüssig. In PHP sieht das so aus:

$body = base64_encode( $body );
		

Automatische Konvertierung

Im Idealfall wird diese Kodierung von einem modernem Mailserver schon übersetzt und die Header angepasst. zB:

Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from base64 to 8bit by smtp.example.org
		

Wobei der 2. Header schon darauf hinweist, dass es sich hier um keinen Standard handelt.

Der Mailbody enthält in diesem Fall nur die 8bit UTF-8 Daten - lediglich der X-MIME-Autoconverted Header weist darauf hin, dass die Nachricht einst base64 kodiert war.

Weiterführende Informationen

Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies

Creative Commons-Lizenzvertrag
Diese Inhalt ist unter einer Creative Commons-Lizenz lizenziert.
Geschrieben von Christian Sagmüller <christian@sagmueller.net>

Valid XHTML 1.0! Valid CSS! Get Firefox!