Magazine

Stocker du texte UTF-8 correctement dans une base MySQL

Publié le 23 janvier 2008 par Jpfox

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&eacute; : <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 &agrave; 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&eacute;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&ecirc;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>

Retour à La Une de Logo Paperblog

A propos de l’auteur


Jpfox Voir son profil
Voir son blog

l'auteur n'a pas encore renseigné son compte l'auteur n'a pas encore renseigné son compte

Dossier Paperblog