Encoding a euro symbol in email subject lines

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.

Share This Article

Related Articles


Lazy loading background images to improve load time performance

Lazy loading of images helps to radically speed up initial page load. Rich site designs often call for background images, which can't be lazily loaded in the same way. How can we keep our designs, while optimising for a fast initial load?

Idempotency - what is it, and how can it help our Laravel APIs?

Idempotency is a critical concept to be aware of when building robust APIs, and is baked into the SDKs of companies like Stripe, Paypal, Shopify, and Amazon. But what exactly is idempotency? And how can we easily add support for it to our Laravel APIs?

Calculating rolling averages with Laravel Collections

Rolling averages are perfect for smoothing out time-series data, helping you to gain insight from noisy graphs and tables. This new package adds first-class support to Laravel Collections for rolling average calculation.

Slack Mobile Problems After Enabling 2FA

Two Factor Authentication is an important method for ensuring account security. When I added it to my work Slack account, the mobile app refused to let me back into my workspace. Fortunately, there's a fix, though it does involve jumping through a few hoops!

More