back
Emails are tricky. There's so many legacy systems to keep track of.

Google Mail does it this way:

  1. Detect character encoding

  2. If it's ASCII, leave as ASCII

  3. If it's ISO-8859-1, deliver as ISO-8859-1/quoted printable

  4. If it's UTF-8, but only contains characters that could also be displayed as ISO-8859-1, convert to and deliver as ISO-8859-1/quoted printable.

  5. If it's UTF-8, deliver as UTF-8/base64



That's neat, the system tries progressively newer encodings that are progressively more functional, but also more likely to break. The oldest encoding with the least necessary functionality, which also is the most compatible, is used.

Here's how to do that in PHP:
function email_header_encode($in) { // $in is assumed to be UTF-8, which happens // to coincide with ASCII if there are no special chars $encoding = mb_detect_encoding($in); // If the UTF-8 string contains special chars in the ISO-8859-1 range, use that if ($encoding == 'UTF-8' && mb_detect_encoding(utf8_decode($in) == 'ISO-8859-1')) { $in = utf8_decode($in); $encoding = 'ISO-8859-1'; } switch ($encoding) { case 'ASCII': $out = $in; break; case 'ISO-8859-1': $out = '=?ISO-8859-1?Q?'.quoted_printable_encode($in).'?='; break; case 'UTF-8': $out = '=?UTF-8?B?'.base64_encode($in).'?='; break; } return $out; } And here's how to send a plain text mail. '; $from_name = 'Mick Jagger'; $from_email = 'mick@jagger.invalid'; $from = email_header_encode($from_name) . '<' . $from_email . '>'; $subject = email_header_encode('Provide satisfactory violence'); $header = 'From: ' . $from . "\n" . 'MIME-Version: 1.0' . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n"; mail($to, $subject, $message, $header);