Encoding a euro symbol in email subject lines
Character encoding in PHP can be fun at the best of times. Trying to send a non-ASCII character in a html email – a euro symbol, for example – can be just such one of those times.
Setting up html and text versions of a mail is pretty straight-forward. What gets a bit trickier is trying to add a non-ASCII character to the subject line – the euro symbol (€) in this case. The problem here is that the subject line is part of the email headers rather than the body, and the headers by default can only contain ASCII characters. Trying to send the symbol through the subject like a regular string can end up with it appearing as “€” or “?”, depending on the recipient’s mail client.
So what’s the solution?
The way around this is to embed the symbol as a MIME Encoded-Word in the subject. And what, pray tell, is that, I hear you cry? A MIME Encoded-Word…
.. uses a string of ASCII characters indicating both the original character encoding (the “charset”) and the content-transfer-encoding used to map the bytes of the charset into ASCII characters.
The form is: “=?charset?encoding?encoded text?=”.
So, in the case of our euro symbol, the MIME Encoded-Word format is:
=?UTF-8?B?4oKs?=
Fortunately, we don’t need to craft this string by hand for each and any non-ASCII character we may want. Using PHP’s mb_encode_mimeheader function, it’s fairly trivial to ensure the characters display ok.
Euro symbol in email subject lines – the code
Below is the php code for embedding a euro symbol in a mail’s subject line.
// Subject (html entities encoded from earlier part of app..)
$subject = "Special deal - only €9.99!";
$subject = str_replace(
'€'
, mb_encode_mimeheader('€', 'UTF-8')
, $subject
);
// Now send mail as normal..
And that’s all there is to it! Euro symbols should now show correctly in your subject lines across all manner of modern mail clients.
Just one more thing...
When it comes to character encoding and PHP, it’s never quite as simple as it looks. If your application isn’t UTF-8 by default, then PHP will ignore the ‘UTF-8’ parameter given to mb_encode_mimeheader, and instead use the current encoding of the application (commonly something like ISO-8859-1).
If you’re in this situation, the above can be adjusted without much heartache as follows:
// Subject (html entities encoded from earlier part of app..)
$subject = "Special deal - only €9.99!";
// Track our current encoding for later reset
$mbEnc = mb_internal_encoding();
// Force UTF-8 for now
mb_internal_encoding('UTF-8');
$subject = str_replace(
'€'
, mb_encode_mimeheader('€', 'UTF-8')
, $subject
);
// Restore encoding so the rest of our app carries on as before
mb_internal_encoding($mbEnc);
// Now send mail as normal..
And that will ensure that the euro symbol appears correctly in your subject lines, regardless of your app’s current encoding.
International PHP Conference
Munich, November 2024
In November 2024, I'll be giving a talk at the International PHP Conference in Munich, Germany. I'll be talking about the page speed quick wins available for backend developers, along with the challenges of policing dangerous drivers, the impact of TV graphics on web design, and the times when it might be better to send your dev team snowboarding for 6 months instead of writing code!
Get your ticket now and I'll see you there!