3

I have a rather simple function to send an email. I started to implement translated versions of the email and with this came special characters such as é and ó. Whenever I have those in the subject of the email, the email creates trouble by causing BAD_HEADER errors in my amavis.

Apparently it is not 8bit encoded, which makes sense at first. However, i can't find anywhere on the net any guide or explanation how to encode the subject properly.

Just for fun I tried é instead of é, and of course the problem was handled. but at the same time the email arrived with é in the subject, instead of é.

Here is the script I have currently:

function sendEmail() {

    // Build HTML version
    ob_start();
    include('emailhtml.php');
    $msgHTML = ob_get_contents();
    ob_end_clean();

    // Build TXT version
    ob_start();
    include('email.php');
    $msgTxt = ob_get_contents();
    ob_end_clean();


    // Subject & headers
    $subject = "áéíóú";
    $boundary = md5(uniqid(rand())); 
    $headers   = array();
    $headers[] = "MIME-Version: 1.0";
    $headers[] = "Content-Type: multipart/alternative; boundary = ".$boundary;
    $headers[] = "From: ".$from." <".$from_email.">";
    $headers[] = "Reply-To: ".$reply2_email;

    // Plain text version of message
    $body = "--$boundary\r\n" .
       "Content-Type: text/plain; charset=UTF-8\r\n" .
       "Content-Transfer-Encoding: base64\r\n\r\n";
    $body .= chunk_split(base64_encode($msgTxt));

    // HTML version of message
    $body .= "--$boundary\r\n" .
       "Content-Type: text/html; charset=UTF-8\r\n" .
       "Content-Transfer-Encoding: base64\r\n\r\n";
    $body .= chunk_split(base64_encode($msgHTML));
    $body .= "--$boundary--\r\n";

    // BAM! Shoot it off...
    mail($receiver, $subject, $body, implode("\r\n", $headers));
}
Kolja
  • 860
  • 4
  • 10
  • 30
  • 1
    You need to encode the subject, either with quoted printable or base64. Here is an example: http://stackoverflow.com/questions/13645869/how-to-set-an-umlaut-u-in-the-mail-subject – grebneke Jan 16 '14 at 17:50
  • @grebneke thanks, I am trying this solution. – Kolja Jan 16 '14 at 19:03
  • @grebneke I tried to use this quoted_printable_encode() as given in your link. But my script stops completely when I use this. :/ – Kolja Jan 16 '14 at 19:24

4 Answers4

5

Encoding mail headers

The Subject: header needs to be encoded if it contains any characters outside the ASCII character set.

Encoding type

There are two encodings you can use: Quoted Printable or Base64. A typical encoded Subject header for content áéíóú looks like this:

// Using Quoted Printable encoding:
Subject: =?ISO-8859-1?Q?=C3=A1=C3=A9=C3=AD=C3=B3=C3=BA?=

// Using Base64 encoding:
Subject: =?ISO-8859-1?B?w6HDqcOtw7PDug==?=

The preferred way

If your PHP is compiled with Multibyte String Functions, you should use mb_encode_mimeheader():

$subject = "áéíóú";
$encoded_subject = mb_encode_mimeheader($subject);
print $encoded_subject;
// output: =?UTF-8?B?w4PCocODwqnDg8Ktw4PCs8ODwro=?=

The manual way

If you cannot use mb_encode_mimeheader() you could use some third-party PHP library, or create your own encoding function.

$subject = "áéíóú";
$encoded_subject = "=?ISO-8859-1?Q?" . quoted_printable_encode($subject) . "?=";
print $encoded_subject;
// Output: =?ISO-8859-1?Q?=C3=A1=C3=A9=C3=AD=C3=B3=C3=BA?=

The gory details

Doing MIME-encoding correctly is not trivial. To learn everything about it, you should begin by studying RFC 2047 and RFC 2045

grebneke
  • 4,414
  • 17
  • 24
  • Thanks, this did the job. I tried first the quoted printable, but then found out that my provider only runs on php 5.2.17, while quoted printable per documentation was added with 5.3. I use now Base64 and it works like a charm – Kolja Jan 17 '14 at 10:24
1

What works for me is: $Subject = "=?UTF-8?B?". base64_encode($Subject). "?=";

and this does the reverse:

function Subject($subject) {
    $prefix = "=?UTF-8?B?";
    return (stristr($subject,$prefix) === false ? 
                                    $subject : 
        base64_decode(substr(substr($subject,10),0,-2) ));
}
Elliptical view
  • 3,338
  • 1
  • 31
  • 28
0

You have this: $subject = $subject;, but you never actually set $subject. So, you're passing an uninitialized value to mail(), which gets treated as null and causes problems.

elixenide
  • 44,308
  • 16
  • 74
  • 100
-1

$asuntoUFT8 = "Example te desea un Feliz Cumpleaños !!";

$asunto = "=?UTF-8?B?".base64_encode($asuntoUFT8)."=?=";

  • 1
    Please take a moment to read through the [editing help](//stackoverflow.com/editing-help) in the [help]. Formatting on Stack Overflow is different than other sites. – Dharman Sep 20 '19 at 21:51
  • A very similar answer already exists in this thread, please explain how yours is different. – Dharman Sep 20 '19 at 21:51