Since 1998

Handling the euro sign in utf8_encode

Who has never come across that odd little diamond-shaped character in the middle of a word on a web page?
Worse still, on their own web page!
What is it trying to say? It’s a character not recognised by the utf8 encoding.
Some smart alecs will use utf8_encode, but the euro won’t get through . . .
This article is aimed at readers with some notions of webmastering, in particular who have come across HTML headers and character encoding.  If these notions are unfamiliar to you, please read up on them on the Internet.

A typical example of an iso-8859-1 character expressed in utf8. The browser shows it with its default 'not found' character, because it wasn't utf8-encoded in the incoming stream.
Typically, in the case we’re interested in, this little diamond-shaped character is ISO-8859-1 expressed in utf8.  Decoded, this means the header of the web page in question is utf8:
The page in question tells the browser to use the utf8 character set. This means upper characters must be utf8-encoded beforehand.
, so the browser expects special characters to arrive encoded on more than one byte (like this e acute), but suddenly it sees a single byte arrive, which is the ISO-8859-1 form of e acute.  Now, no utf8 character matches that value, so it displays its default“not found”, i.e.  this diamond.

This problem is typically found in UTF8-encoded pages that gather content from several sources, some encoded in UTF8 and some in ISO-8859-1.  Here, for example, the image titles arrive in ISO-8859-1.  The encodings are heterogeneous.

How do you fix this problem?

The short answer
The short answer is to use the utf8_encode() function to utf8-encode, within your web page, any text likely to contain non-standard characters.  That way, the browser receiving the text will render these characters properly, as long as your web page imposes charset=UTF-8 on it.

If your scripting language is PHP, I’d even recommend using an alias you can define yourself in your function library: my home-made function utf8_encode2(), whose code is shown below.  Its huge advantage is that it encodes some characters ignored by utf8_encode(), because they belong to other character sets.  In this case cp1252, which includes the euro.


<?php
function utf8_encode2($str) {

    
$final_str = $str;

    
$final_str = str_replace('œ', '&#339;',  $final_str);
    
$final_str = str_replace('’', '&#2019;', $final_str);
    
$final_str = str_replace('“', '&#201C;', $final_str);
    
$final_str = str_replace('”', '&#201D;', $final_str);
    
$final_str = str_replace('…', '&#2026;', $final_str);
    
$final_str = str_replace('€', '&#8364;', $final_str);

    
$final_str = utf8_encode($final_str);

    
$final_str = str_replace(utf8_encode('&#339;') , 'Å“',     $final_str);
    
$final_str = str_replace(utf8_encode('&#2019;'), '’', $final_str);
    
$final_str = str_replace(utf8_encode('&#201C;'), '“', $final_str);
    
$final_str = str_replace(utf8_encode('&#2026;'), '…', $final_str);
    
$final_str = str_replace(utf8_encode('&#201D;'), '”', $final_str);
    
$final_str = str_replace(utf8_encode('&#8364;'), '€', $final_str);

    return 
$final_str;
}
?>


The long answer
With this one, you won’t even need utf8_encode() to pass your text into the HTML stream, nor any htmlentities() etc . . .   It’s about following the best practice of saving your web pages in utf8 format.  You’ll need to make sure the HTML header of the page to display declares the utf8 charset, as seen in image 2 above.
That way you can afford any fancy stuff, euro, the weirdest characters, and everything will hold together, even on browsers made in China.

So if utf8 solves everything, why use conversion functions?
The first good reason to use them is precisely to convert data to UTF8 as part of a migration.
The second reason is to deal with mixed sources, when the developer doesn’t have full control over the code or over how the data is encoded.  They have to juggle with what they’ve got.  Hence the value of having a library of conversion functions at hand.
(13770 views)
created Monday 12 September 2011
revised Friday 13 November 2026 by
Would you accept our confidentiality policy? It is about cookies and personal data...