De nombreux projets PHP (moteur de blog, CMS...) gèrent les données au format UTF-8. Malheureusement, beaucoup ne le font pas correctement : les tables MySQL sont créées avec l'encodage latin1 par défaut et le texte encodé en UTF-8 par l'application y est stocké tel quel.
Lorsque l'on regarde le contenu de ces tables avec phpmyadmin, on voit alors les lettres accentuées remplacées par deux caractères sans rapport. Il devient difficile d'exploiter efficacement ces données.
L'erreur généralement commise est double :
- table créée en latin1 pour stocker de l'utf-8
- utilisation des fonctions mysql_* en latin1 avec des données utf8
Pour utilisation optimale de MySQL il suffit pourtant de peu de chose :
- ajouter DEFAULT CHARSET=utf8 à la fin des requêtes de création de table
- appeler la fonction mysql_set_charset("utf8") juste après la connexion pour indiquer à MySQL que le client échangent les données avec le serveur avec l'encodage UTF-8. On peut aussi exécuter une requête SQL (si on utilise un framework ou PHP<5.2.3 ou MySQL<5.0.7) qui a le même résultat : $db->query("SET NAMES UTF8");
Voici un petit exemple complet :
[php] <?php // Affichage de la page en UTF-8 header("Content-type: text/html; charset=UTF-8"); ?> <html> <body> <form method="POST" action="<?=$_SERVER['REQUEST_URI']?>"> Entrez du texte accentué : <input name="texte" /> <br/> <input type="submit" value="Enregistrer dans la base" /> </form> <?php // Connexion et sélection de la base $lnk = mysql_connect("localhost", "root", "fox") or die("Impossible de se connecter au serveur"); mysql_select_db("test", $lnk) or die("Connexion à la base impossible"); // Indiquer à mysql que l'on va communiquer avec lui en utf8 mysql_set_charset("utf8", $lnk); // Il est aussi possible de changer l'encodage à l'aide d'une requête SQL // si les fonctions mysql_* sont encapsulés dans un framework // ou si PHP<5.2.3 ou MySQL<5.0.7 // ex : mysql_query("SET NAMES UTF8"); // ou $db->query("SET NAMES UTF8"); // Création de la table encodée en UTF8 $sqlCreate = "CREATE TABLE IF NOT EXISTS tableA ( champsA int(11) NOT NULL auto_increment, champsB text NOT NULL, PRIMARY KEY (champsA) ) ENGINE=MyISAM DEFAULT CHARSET=utf8"; if(mysql_query($sqlCreate)) { echo "Création de la table OK.<br/>\n"; } // Insertion du texte saisie dans le formulaire if(isset($_POST['texte'])) { $sqlInsert = sprintf("INSERT INTO tableA(champsB) VALUES('%s')", mysql_real_escape_string($_POST['texte'])); if(!mysql_query($sqlInsert)) { echo "Insertion dans la table impossible.<br/>\n"; } } $sqlSelect = "SELECT * FROM tableA"; // Lecture des données $result = mysql_query($sqlSelect) or die("Requête impossible sur la table."); // Afficher des résultats en HTML echo "<table>\n"; while ($line = mysql_fetch_assoc($result)) { echo "\t<tr>\n"; foreach ($line as $col_value) { echo "\t\t<td>$col_value</td>\n"; } echo "\t</tr>\n"; } echo "</table>\n"; // Libération des résultats mysql_free_result($result); // Fermeture de la connexion mysql_close($lnk); ?> </body> </html>