C’est le bug le plus coûteux que nous ayons rencontré sur un projet multilingue marocain, et il ne produit jamais de message d’erreur.
Ce qui se passe réellement
MySQL n’interdit pas l’insertion de caractères arabes dans une colonne latin1. Il les convertit. Chaque caractère arabe occupe deux octets en UTF-8 ; latin1 les interprète comme deux caractères distincts et les remplace par des points d’interrogation ou du mojibake. L’insertion réussit. Le code applicatif ne voit rien.
Pourquoi le bug apparaît tard
En développement, vous testez souvent avec du texte français. Le français passe sans dommage en latin1. La corruption ne se déclenche qu’au moment où un vrai client saisit un vrai menu en arabe — c’est-à-dire en production, sur des données que personne n’a sauvegardées.
La vérification, avant la première insertion
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'votre_base'
AND TABLE_COLLATION NOT LIKE 'utf8mb4%';
Toute ligne retournée est une bombe à retardement. La correction :
ALTER TABLE ma_table
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
utf8 ne suffit pas
L’ancien utf8 de MySQL stocke trois octets par caractère. Il gère l’arabe, mais pas les emoji ni certains caractères étendus. utf8mb4 est le seul choix défendable aujourd’hui.
Ce que nous en avons tiré
La vérification du charset fait maintenant partie de notre checklist de mise en production, au même titre que les sauvegardes. Un contrôle de trente secondes contre une perte de données irréversible : le calcul n’est pas difficile.
