Sonderzeichen und Umlaute reisen nicht ohne Weiteres unbeschadet durch das Mailsystem. Damit eine Nachricht auf jedem Server so ankommt, wie sie abgeschickt wurde, braucht es ein passendes Encoding. Die PHP-Funktion quoted_printable_encode() liefert genau das für Mail-Bodys mit überwiegend ASCII-Inhalt. Dieses Tutorial zeigt das Output-Format, die RFC-Regeln, den Versand mit korrekten MIME-Headern und den Vergleich mit base64_encode.
Was macht die Funktion PHP quoted_printable_encode()?
Wer in PHP eine E-Mail mit Umlauten oder anderen Sonderzeichen verschickt, braucht ein Encoding, das die Nachricht über Mailserver hinweg ohne Datenverlust transportiert. Genau hier setzt PHP quoted_printable_encode an: Die Funktion wandelt einen String in das MIME-Quoted-Printable-Format um, das nach RFC 2045 definiert ist, und gibt das Ergebnis als kodierten String zurück. ASCII-Zeichen bleiben unverändert, alle anderen Bytes werden als Hex-Notation in der Form =XX kodiert.

Bevor das Output-Format und die RFC-Regeln im Detail folgen, ein Blick darauf, warum gerade dieses Encoding für überwiegend ASCII-Inhalte die richtige Wahl ist.
Das macht den Output für einen Mailserver maximal verträglich, weil keine 8-Bit-Zeichen direkt durchs Netz reisen. Gleichzeitig bleibt der kodierte Text für Menschen lesbar, sofern der Anteil an Sonderzeichen klein ist. PHP quoted_printable_encode ist damit das richtige Werkzeug für überwiegend ASCII-Inhalt mit gelegentlichen Umlauten, etwa für Bestätigungsmails oder einfache Newsletter.
Output-Format mit =XX-Notation verstehen
Das Quoted-Printable-Format folgt einer einfachen Regel: ASCII-Zeichen 33 bis 126 (mit Ausnahme des Gleichheitszeichens) bleiben unverändert, alles andere wird zu =XX, wobei XX der Hex-Wert des Bytes ist. Ein deutsches ue (UTF-8: 0xC3 0xBC) wird zu =C3=BC.
<?php
$text = "Mueller schreibt: Ende.";
echo quoted_printable_encode($text);
/* Mueller schreibt: Ende.
reines ASCII bleibt unveraendert */
$mitUmlaut = "M\xC3\xBCller";
echo quoted_printable_encode($mitUmlaut);
/* M=C3=BCller - das ue als zwei Hex-Bytes */
Das Gleichheitszeichen selbst wird zu =3D, weil es das Marker-Zeichen ist. Ein Tab oder ein Leerzeichen am Zeilenende wird ebenfalls kodiert, weil Mailserver am Zeilenende solche Zeichen oft entfernen würden. Diese Details kennt PHP quoted_printable_encode und nimmt sie dem Entwickler ab.
Syntax und die Zeilenlängen-Regel von 76 Zeichen
Die Signatur ist denkbar einfach: ein String rein, ein String raus.
<?php
quoted_printable_encode(string $string): string
Im Hintergrund passiert allerdings mehr als nur die =XX-Konvertierung. RFC 2045 schreibt vor, dass eine Zeile in einer quoted-printable kodierten Nachricht maximal 76 Zeichen lang sein darf. PHP quoted_printable_encode bricht längere Zeilen automatisch um und setzt am Zeilenende ein = als sogenannten weichen Zeilenumbruch, der dem Empfänger sagt: "die nächste Zeile gehört eigentlich noch dazu".
<?php
$lang = str_repeat('PHP ist toll. ', 20);
$encoded = quoted_printable_encode($lang);
echo $encoded;
/* die Zeilen werden automatisch nach max. 76 Zeichen mit =\r\n umgebrochen */
Diese Begrenzung ist beim Aufbau von HTML-Mails zu beachten. Wer einen langen <style>-Block einfügt, sollte sich nicht wundern, dass mitten im Code Zeilenumbrüche auftauchen. Sie sind syntaktisch legal und der Empfänger fügt sie wieder zusammen, doch im Quelltext wirkt es zunächst irritierend.
E-Mail mit korrekten MIME-Headern versenden
PHP quoted_printable_encode entfaltet seinen Nutzen erst in Kombination mit den richtigen MIME-Headern. Der Body wird kodiert, der Header Content-Transfer-Encoding: quoted-printable teilt dem Mailclient mit, wie er die Nachricht zu interpretieren hat. Das Subject braucht ein eigenes Encoding, dafür eignet sich mb_encode_mimeheader().
<?php
$an = 'kunde@example.com';
$subject = mb_encode_mimeheader(
'Bestaetigung Ihrer Bestellung',
'UTF-8',
'Q'
);
$body = quoted_printable_encode(
"Sehr geehrte Damen und Herren,\n\n"
. "vielen Dank fuer Ihre Bestellung.\n"
. "Mit freundlichen Gruessen"
);
$headers = "MIME-Version: 1.0\r\n"
. "Content-Type: text/plain; charset=UTF-8\r\n"
. "Content-Transfer-Encoding: quoted-printable\r\n"
. "From: noreply@beispiel.de";
mail($an, $subject, $body, $headers);
Diese Kombination produziert eine RFC-konforme Mail. Wer die PHP-Funktion mail() im Einsatz hat, sollte sich angewöhnen, immer alle drei MIME-Header (Version, Content-Type, Content-Transfer-Encoding) zu setzen. Sonst kann es passieren, dass Mailserver die Nachricht in 7-Bit-Klassik umsetzen und Sonderzeichen verloren gehen.
Round-Trip mit quoted_printable_decode
Jedes Encoding braucht einen passenden Decoder. Das Gegenstück zu PHP quoted_printable_encode ist quoted_printable_decode(). Ein Round-Trip ist ein guter Sanity-Check, wenn man sich nicht sicher ist, ob die Pipeline korrekt arbeitet.
<?php
$original = 'Mueller hat geschrieben: schoen!';
$encoded = quoted_printable_encode($original);
$decoded = quoted_printable_decode($encoded);
echo $encoded . "\n";
echo $decoded . "\n";
echo ($original === $decoded ? 'Identisch' : 'Unterschiedlich');
/* Identisch */
Wer im Backend eingehende Mails verarbeitet (etwa für einen Support-Ticket-Eingang), trifft früher oder später auf quoted-printable kodierte Bodys. Die Decode-Funktion ist dann das richtige Werkzeug, um die Inhalte wieder lesbar zu machen.
quoted_printable_encode vs base64_encode
Die häufigste Frage im Code-Review ist, ob PHP quoted_printable_encode oder base64_encode genutzt werden soll. Die Antwort hängt vom Anteil der Sonderzeichen ab. Bei überwiegend ASCII-Inhalt ist quoted-printable kürzer und besser lesbar, bei überwiegend binären Daten oder vielen Sonderzeichen ist Base64 effizienter.
<?php
$text = 'Mueller-Newsletter mit Sonderzeichen aeoeuess';
echo 'QP-Laenge: '
. strlen(quoted_printable_encode($text)) . ' Bytes' . "\n";
echo 'Base64-Laenge: '
. strlen(base64_encode($text)) . ' Bytes' . "\n";
/* Bei wenigen Sonderzeichen ist QP kuerzer.
Bei vielen Sonderzeichen oder Binaerdaten gewinnt Base64. */
Faustregel für den Body: PHP quoted_printable_encode für Plain-Text-Mails mit Umlauten, Base64 für HTML-Mails mit eingebetteten Bildern oder Anhängen. Wer Anhänge transportiert, kommt um Base64 nicht herum, weil Bytes ausserhalb von ASCII anders nicht sicher übertragbar sind.
Subject-Encoding mit mb_encode_mimeheader
PHP quoted_printable_encode arbeitet ausschliesslich auf dem Body. Header-Zeilen wie Subject, From oder To brauchen ein anderes Encoding, das von RFC 2047 definiert wird. Die Funktion mb_encode_mimeheader() übernimmt das.
<?php
$subject = mb_encode_mimeheader(
'Bestaetigung Ihrer Bestellung Nr. 42',
'UTF-8',
'Q' // Q = quoted-printable, B = base64
);
echo $subject;
/* =?UTF-8?Q?Best=C3=A4tigung_Ihrer_Bestellung_Nr=2E_42?= */
Das Format =?charset?Q?...?= ist die korrekte Header-Codierung. Wer das versäumt, sieht Umlaute in der Betreffzeile als kaputte Bytes oder als seltsame Sonderzeichen. Die Funktion mb_encode_mimeheader macht das robust und kennt die Regeln aus RFC 2047 im Detail.
Praxis-Hinweis auf Symfony Mailer und PHPMailer
Wer eine moderne PHP-Anwendung baut, sollte für den E-Mail-Versand selten manuell mit PHP quoted_printable_encode hantieren. Bibliotheken wie PHPMailer, Symfony Mailer oder Laravel Mail übernehmen Encoding, MIME-Header und SMTP-Verbindung in einer kohärenten API. Der Aufruf reduziert sich auf das Setzen von Empfänger, Subject und Body, alles andere passiert im Hintergrund.
<?php
/* Beispiel mit PHPMailer (Pseudo-Code) */
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->Encoding = 'quoted-printable';
$mail->Subject = 'Bestaetigung mit Umlauten';
$mail->Body = 'Sehr geehrte Damen und Herren ...';
$mail->send();
/* PHPMailer ruft intern quoted_printable_encode auf */
PHP quoted_printable_encode bleibt trotzdem relevant, etwa beim Verarbeiten eingehender Mails, beim Schreiben eigener Bibliotheken oder beim Debuggen. Wer versteht, wie das Encoding funktioniert und welche Funktionen wie quoted_printable_decode, mb_encode_mimeheader oder base64_encode rundherum gehören, kann auch dann entscheiden, ob ein Bug im Encoding, in der Bibliothek oder beim Empfänger liegt.
flowchart TD
A[Original-Text mit Umlauten] --> B[quoted_printable_encode]
B --> C["Body als QP-String mit =XX"]
C --> D["mail mit Header CTE: quoted-printable"]
D --> E[Mailserver Transport]
E --> F[Empfaenger-Client]
F --> G[quoted_printable_decode beim Lesen]
G --> H[Original-Text wiederhergestellt]
imap_8bit() und die Mbstring-Deprecation
Im PHP-Universum gibt es eine zweite Funktion, die exakt das gleiche Encoding produziert: imap_8bit(). Sie gehört zur IMAP-Erweiterung und ist historisch älter als quoted_printable_encode. Beide Aufrufe liefern identische Ergebnisse, solange die IMAP-Extension kompiliert ist.
<?php
$text = "Mueller schreibt: Ende.";
echo quoted_printable_encode($text) . "\n";
echo imap_8bit($text) . "\n";
/* beide liefern identische Ausgabe */
In Neuprojekten ist quoted_printable_encode die bessere Wahl, weil es ohne IMAP-Extension funktioniert und in jeder Standard-PHP-Installation verfügbar ist. imap_8bit taucht meist nur noch in älteren Codebasen auf und sollte beim Refactoring durch das Pendant ersetzt werden.
Eine wichtige Klarstellung zu PHP 8.2 und höher: Die Mbstring-Encodings Quoted-Printable, Base64, UUencode und HTML-ENTITIES sind ab PHP 8.2 als deprecated markiert. Das betrifft Aufrufe wie mb_convert_encoding($text, 'Quoted-Printable', 'UTF-8') und liefert inzwischen einen Deprecation-Notice. Die eigenständige Funktion quoted_printable_encode ist davon nicht betroffen und bleibt der empfohlene Weg, um Mail-Bodys in QP zu kodieren. Wer im Bestandscode eine Notice zu deprecated mbstring sieht, sollte den Aufruf entsprechend umstellen.
Fazit
Mit PHP quoted_printable_encode steht ein zuverlässiges MIME-Encoding für E-Mail-Bodys bereit, das Strings mit gelegentlichen Sonderzeichen kompakt und lesbar hält. Die Funktion wandelt 8-Bit-Zeichen in =XX-Notation und beachtet die RFC-2045-Regel von 76 Zeichen pro Zeile. Im Vergleich zu base64_encode bleibt sie die richtige Wahl, solange der Anteil der Sonderzeichen klein bleibt. Für den Subject-Header braucht es zusätzlich mb_encode_mimeheader(), für moderne Projekte sind Bibliotheken wie PHPMailer oder Symfony Mailer die produktivere Wahl. Wer das Format versteht, kann eingehende Mails sauber verarbeiten und debuggen, ohne sich von kryptischen =C3=BC-Kombinationen abschrecken zu lassen.