Accents replaced by é or ? almost always stem from an encoding mismatch between your code, the database connection, and the database itself. Here are the three places you need to align.
The rule: use utf8mb4 everywhere. This is MySQL's full UTF-8, the one that also accepts emojis and rare Asian characters, whereas the older MySQL utf8 stopped at three bytes.
In short: align the three links: the PHP connection in utf8mb4 (in the DSN or with set_charset()), the database and its tables converted to utf8mb4 after a backup, and the pages declared as UTF-8 (<meta charset="utf-8">, files without BOM).
How do I set the encoding of the PHP connection?
This is the most frequently overlooked point: even if the database is in UTF-8, the connection may negotiate a different character set.
With PDO, declare the encoding in the DSN:
$pdo = new PDO(
'mysql:host=localhost;dbname=ma_base;charset=utf8mb4',
$utilisateur,
$motdepasse,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
With mysqli:
$mysqli = new mysqli('localhost', $utilisateur, $motdepasse, 'ma_base');
$mysqli->set_charset('utf8mb4');
Do not use mysql_query("SET NAMES utf8") anymore. The mysql_* extension was removed from PHP 7: this code simply no longer executes. And even back in PHP 5, SET NAMES left the escaping function unaware of the change, which could open an SQL injection vulnerability. Prefer charset=utf8mb4 in the DSN, or set_charset().
How do I convert the database and tables to utf8mb4?
Check the collation from phpMyAdmin, accessible in the Apanel console: Hosting management > Databases > phpMyAdmin.
Databases created from the Apanel console use utf8 (collation utf8_general_ci), MySQL's older utf8 limited to three bytes: this is what makes emojis disappear. To accept them, convert the database and its tables to utf8mb4 as shown below.
To convert an existing table:
ALTER TABLE ma_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
And to ensure future tables follow suit:
ALTER DATABASE ma_base CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Back up before converting. If the data was already saved with the wrong encoding, a conversion may lock in the corruption instead of fixing it. The console allows you to restore a database: see Restore a database.
How do I declare the encoding of pages to the browser?
Declare the encoding in your pages:
<meta charset="utf-8">
And ensure your source files are themselves saved as UTF-8 without BOM: most editors offer this option when saving.
The server, for its part, already announces UTF-8 by default. This setting, Default charset, is found in Hosting management > Website > Apache configuration, and should only be modified if your site is actually in a different encoding.
How do I recognize the problem?
| What you see |
What is happening |
é instead of é |
UTF-8 text is displayed as if it were ISO-8859-1. The data is healthy: the encoding declaration is missing. |
? or � |
The character was lost during writing. The data is damaged in the database: it must be re-saved after fixing the connection. |
| Emojis disappear, the rest is fine |
The table is in utf8 (3 bytes) and not in utf8mb4. |
Going further