Développement et bases de données

MySQL 8, changement d'encodage des caractères de latin1 à utf8mb4

Vérifié le 3 min de lecture encodage MySQL

Les valeurs par défaut de l'éditeur sont passées de latin1 dans MySQL 5.7 à utf8mb4 dans MySQL 8. La configuration d'un serveur peut être différente. Mettre à jour MySQL ne convertit pas automatiquement toutes les tables existantes ; le jeu de caractères que l'application négocie à la connexion compte aussi.

Ce changement ne pose généralement pas de problème, car les applications définissent le jeu de caractères à utiliser dans la couche de connexion à MySQL. Mais certaines applications très anciennes ou certains développements sur mesure ne le font pas : après le changement, les données peuvent alors s'afficher à l'écran avec des caractères « étranges ».

Avant de modifier quoi que ce soit, vérifiez l'encodage réel des tables et la configuration attendue par l'application. Forcer latin1 n'est correct que lorsque le projet et ses données utilisent encore ce jeu de caractères ; cela ne permet pas de réparer des données déjà converties ou stockées avec un encodage incorrect.

Vérifier où apparaît le problème

Examinez un échantillon de texte connu dans la base et sur le site, sans l'enregistrer à nouveau pour l'instant. Si phpMyAdmin l'affiche correctement mais pas votre application, vérifiez la connexion et l'encodage de la réponse HTML. S'il est déjà mal stocké, changer la connexion ne le réparera pas. Travaillez sur une copie avant d'essayer de convertir des données.

Depuis la même connexion que celle de l'application, vous pouvez exécuter :

SELECT @@character_set_client, @@character_set_connection,
       @@character_set_results, @@collation_connection;

L'exécuter depuis phpMyAdmin affiche la session de phpMyAdmin, pas celle de votre application. Vérifiez aussi le jeu de caractères des colonnes concernées ; il peut différer de celui défini par défaut pour la table.

Conserver temporairement une application en latin1

Configurez le jeu de caractères depuis le connecteur lui-même. Avec MySQLi :

mysqli_set_charset($connection, 'latin1');

Avec PDO, incluez-le dans le DSN lors de la création de la connexion :

$dsn = 'mysql:host=localhost;dbname=BASE_DE_DATOS;charset=latin1';
$connection = new PDO($dsn, $user, $password);

N'utilisez pas mysql_select_db() ni mysql_query() : elles appartiennent à l'ancienne extension mysql, supprimée de PHP depuis la version 7. Il n'est pas non plus recommandé d'envoyer SET NAMES manuellement avec MySQLi, car mysqli_set_charset() maintient synchronisé le jeu de caractères qu'utilise le client pour échapper les chaînes.

Préparer la mise à jour

Si le projet prend en charge l'Unicode complet, planifiez la conversion en utf8mb4 avec un clone, une sauvegarde récupérable et des tests de lecture et d'écriture. Ne passez pas en latin1 une application qui utilise déjà correctement utf8mb4.

Cela peut aussi vous aider

Quelque chose cloche ou a changé ? Racontez-nous et nous le vérifions.