utf8_decode()
The utf8_decode() function is a PHP built-in function that converts a string with UTF-8 encoding to ISO-8859-1 encoding. UTF-8 is a popular character encoding
The utf8_decode() function is a PHP built-in function that converts a string from UTF-8 encoding to ISO-8859-1 (also called Latin-1). UTF-8 can represent every Unicode character, while ISO-8859-1 is a single-byte encoding that only covers the first 256 Unicode code points (Western European letters, digits, and punctuation).
This page explains what utf8_decode() does, when you actually need it, the modern replacement, and how it behaves with characters that fall outside ISO-8859-1.
When (and whether) to use it
You only need utf8_decode() when you are feeding UTF-8 text into an older system that only understands ISO-8859-1 — for example a legacy database column, a fixed-width report, or a third-party API that predates Unicode. For anything new, keep your data in UTF-8 end to end and you will never need this function.
utf8_decode() is deprecated as of PHP 8.2 and will be removed in a future version. Replace it with mb_convert_encoding($string, 'ISO-8859-1', 'UTF-8') (the mbstring extension) or iconv('UTF-8', 'ISO-8859-1', $string). The opposite conversion is done by utf8_encode().
A key limitation: ISO-8859-1 has no slot for characters such as €, ™, emoji, or any non-Latin script. When utf8_decode() meets a character it cannot represent, it replaces it with a question mark (?) — the original character is lost. This is why the function is lossy and why staying in UTF-8 is almost always the better choice.
Syntax
The syntax of the utf8_decode() function is as follows:
utf8_decode(string $string): string| Parameter | Description |
|---|---|
$string | The UTF-8 encoded string to convert to ISO-8859-1. |
Return value: the converted ISO-8859-1 string. Bytes that are not valid UTF-8, and characters that have no ISO-8859-1 equivalent, are turned into a question mark (?).
Usage Examples
Let's take a look at some practical examples of using utf8_decode() in PHP.
Example 1: Converting UTF-8 Encoded Text to ISO-8859-1
The string "Zoë" is stored in your script as UTF-8, where the ë takes two bytes (c3 ab). After decoding, ë becomes the single ISO-8859-1 byte eb. We print the raw bytes with bin2hex() so the byte-level change is visible:
Converting UTF-8 Encoded Text to ISO-8859-1 in PHP
The output is:
5a6febThe four UTF-8 bytes (Z, o, and the two-byte ë) collapse to three ISO-8859-1 bytes: 5a (Z), 6f (o), and eb (ë). The string is now one byte shorter because the accented character is encoded in a single byte instead of two.
Example 2: Characters that cannot be represented
Because ISO-8859-1 only has 256 code points, any character outside that range is lost. The euro sign (€) is a classic example — it does not exist in Latin-1:
<?php
echo utf8_decode("Price: €5"); // Price: ?5
?>The € is replaced with ?. If you need to preserve characters like this, do not convert to ISO-8859-1 — keep the text in UTF-8, or use a richer target encoding.
Example 3: Reading UTF-8 text from XML
SimpleXML always parses XML as UTF-8. If you must hand that text to a Latin-1 system, decode each value as you read it with simplexml_load_file():
Converting UTF-8 Encoded Text from XML in PHP
<?php
$xml = simplexml_load_file("data.xml");
foreach ($xml->item as $item) {
$title = utf8_decode((string) $item->title);
$description = utf8_decode((string) $item->description);
echo "$title: $description\n";
}
?>This loads data.xml, loops over every <item> element, and decodes the <title> and <description> text from UTF-8 to ISO-8859-1. Casting each node to (string) first turns the SimpleXMLElement into a plain string before decoding.
For this example to work, data.xml should contain a structure like this:
<root>
<item>
<title>Example Title</title>
<description>Example Description</description>
</item>
</root>Conclusion
utf8_decode() converts UTF-8 text to ISO-8859-1, dropping any character that Latin-1 cannot represent. It is handy for talking to legacy systems, but it is deprecated in PHP 8.2+ and lossy, so prefer mb_convert_encoding() or iconv() and keep your data in UTF-8 whenever you can.
To go the other direction, see utf8_encode(). For more on working with text in PHP, see the PHP string functions reference.