How to convert these strange characters? (ë, Ã, ì, ù, Ã)
Categories:
Decoding Mojibake: Fixing 'Strange Characters' (ë, Ã, ì, ù, Ã) in PHP/MySQL

Learn to identify, understand, and resolve common character encoding issues (mojibake) like 'ë, Ã, ì, ù, Ã' when working with PHP and MySQL, ensuring proper display of special characters.
Have you ever encountered 'strange characters' like ë, Ã, ì, ù, or à in your web application? This common problem, often referred to as 'mojibake,' occurs when text is encoded in one character set (e.g., UTF-8) but interpreted in another (e.g., Latin-1). This article will guide you through understanding why these characters appear and provide practical solutions for fixing them in your PHP and MySQL applications.
Understanding Character Encoding and Mojibake
Character encoding is the process of assigning a unique number (code point) to each character and then representing that number as a sequence of bytes. UTF-8 is the most widely used character encoding for the web, capable of representing all characters in the Unicode standard. Latin-1 (ISO-8859-1) is an older, single-byte encoding primarily used for Western European languages.
Mojibake happens when a sequence of bytes encoded in one character set is decoded using a different, incompatible character set. The 'ë' pattern is a classic symptom of UTF-8 encoded characters being misinterpreted as Latin-1. For example, a UTF-8 encoded 'é' (which is 0xC3 0xA9 in hex) when read as Latin-1, will display as 'é' because 0xC3 is 'Ã' and 0xA9 is '©' in Latin-1. The characters you're seeing (ë, Ã, ì, ù, Ã) are specific examples of multi-byte UTF-8 characters being incorrectly rendered as single-byte Latin-1 characters.

How UTF-8 to Latin-1 Mojibake Occurs
Common Causes of Encoding Mismatches
Encoding issues can arise at several points in your application's data flow. Identifying the exact point of failure is crucial for a permanent fix. Here are the most common culprits:
- Database Connection: The connection between your PHP application and MySQL might not be explicitly set to UTF-8.
- Database, Table, or Column Collation: The character set and collation settings of your MySQL database, tables, or individual columns might not be UTF-8.
- PHP File Encoding: Your PHP script files themselves might not be saved as UTF-8.
- HTML Meta Tag/HTTP Headers: The browser might not be told to interpret the page as UTF-8, or the server might send incorrect
Content-Typeheaders. - Data Input/Output: Data being read from or written to files, or received from external APIs, might have an incorrect encoding.
Resolving Encoding Issues: A Step-by-Step Approach
To effectively resolve mojibake, you need to ensure that UTF-8 is consistently used across your entire application stack. This involves checking and configuring your database, PHP application, and web server settings.
1. 1. Configure MySQL Database, Table, and Column Collation
Ensure your MySQL database, tables, and columns are set to utf8mb4 character set and utf8mb4_unicode_ci or utf8mb4_general_ci collation. utf8mb4 is preferred over utf8 as it supports a wider range of Unicode characters, including emojis.
To check current settings, use these SQL queries:
SHOW VARIABLES LIKE 'character_set_database';
SHOW VARIABLES LIKE 'collation_database';
SHOW CREATE DATABASE your_database_name;
SHOW CREATE TABLE your_table_name;
To alter settings (be cautious, backup your data first!):
ALTER DATABASE your_database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE your_table_name CHANGE your_column_name your_column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2. 2. Set MySQL Connection Character Set in PHP
This is one of the most critical steps. After establishing a connection to MySQL, you must explicitly tell MySQL that you will be sending and receiving data in UTF-8. Do this immediately after connecting.
Using mysqli (procedural):
$conn = mysqli_connect("localhost", "user", "password", "database");
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
mysqli_set_charset($conn, "utf8mb4");
// Or for older PHP/MySQL versions:
// mysqli_query($conn, "SET NAMES 'utf8mb4'");
Using mysqli (object-oriented):
$conn = new mysqli("localhost", "user", "password", "database");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$conn->set_charset("utf8mb4");
// Or for older PHP/MySQL versions:
// $conn->query("SET NAMES 'utf8mb4'");
Using PDO:
try {
$pdo = new PDO(
'mysql:host=localhost;dbname=database;charset=utf8mb4',
'user',
'password',
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
]
);
} catch (PDOException $e) {
die("Connection failed: " . $e->getMessage());
}
3. 3. Ensure PHP File Encoding is UTF-8
Your PHP script files themselves should be saved with UTF-8 encoding (without BOM - Byte Order Mark). Most modern IDEs and text editors (like VS Code, Sublime Text, Notepad++) allow you to specify the file encoding. If your files are saved in a different encoding, PHP might misinterpret string literals or hardcoded characters.
Check your editor's settings for 'Encoding' or 'Character Set' and ensure it's set to 'UTF-8 without BOM'.
4. 4. Set HTTP Content-Type Header and HTML Meta Tag
Tell the browser to expect UTF-8 content. This can be done via the HTTP Content-Type header or an HTML <meta> tag.
PHP Header (recommended): Add this at the very beginning of your PHP script, before any output is sent:
header('Content-Type: text/html; charset=utf-8');
HTML Meta Tag (fallback): Include this within the <head> section of your HTML:
<meta charset="utf-8">
5. 5. Convert Existing Mojibake Data (If Necessary)
If you already have mojibake in your database, simply changing the settings won't fix the existing garbled data. You'll need to convert it. This is a delicate process and requires backups.
The general approach is to read the data as if it were Latin-1 (the encoding it was misinterpreted as), and then convert it to UTF-8. This can often be done with a double CONVERT in MySQL or using PHP's iconv or mb_convert_encoding functions.
MySQL Double Convert (example - use with extreme caution and backup!):
UPDATE your_table_name
SET your_column_name = CONVERT(CAST(CONVERT(your_column_name USING latin1) AS BINARY) USING utf8mb4)
WHERE your_column_name LIKE '%Ã%'; -- Target only affected rows
PHP Conversion (example):
$mojibake_string = 'école'; // Example string from database
$fixed_string = iconv('ISO-8859-1', 'UTF-8', $mojibake_string);
// Or if it's UTF-8 double-encoded:
// $fixed_string = utf8_decode(utf8_encode($mojibake_string)); // This is a common hack, but iconv is more robust
It's crucial to test these conversions on a development environment with a copy of your production data before applying them to live systems.
utf8mb4 instead of utf8 for MySQL character sets. The original utf8 in MySQL only supports a subset of UTF-8 (up to 3 bytes per character), while utf8mb4 supports the full range (up to 4 bytes per character), including emojis and many less common characters.By systematically addressing character encoding at each layer of your application – from the database to the PHP scripts and the HTTP headers – you can eliminate mojibake and ensure that all special characters are displayed correctly to your users.