web-dev-qa-db-fra.com

Comment faire pour que MySQL retourne UTF-8?

J'utilise PHPUnit pour valider la sortie XML de mon PHP, mais apparemment j'ai des problèmes avec l'encodage des caractères MySQL renvoie. Voici l'erreur que j'obtiens de DOMDocument :

Input is not proper UTF-8, indicate encoding!
Bytes: 0xE9 0x20 0x42 0x65

J'initialise le DOMDocument pour qu'il utilise le bon encodage:

$domDocument = new DOMDocument('1.0','UTF-8');

Et quand je vérifie la sortie de saveXML () en utilisant mb_detect_encoding, le résultat est TF-8 .

J'ai également vérifié tous les appels utilisés pour créer le XML, en utilisant mb_detect_encoding sur tous les paramètres createCDATASection rencontrés et ils sont tous soit UTF-8 ou ASCII (il n'y a pas de nœuds en texte brut, tout est dans - CDATA blocs).

Je pense que le problème vient de l'utilisation d'un caractère 'é' (qui est 0xE9 dans ISO 8859-1 ). La ligne qui ajoute ce caractère à mon XML est:

$domDocument->createCDATASection($place->name);

et mb_detect_encoding ($ place-> name) me donne UTF-8.

Les données ($ place-> name) sont extraites d'une base de données MySQL. Cette base de données a le jeu de caractères UTF-8.

Voici un exemple de code:

$query = sprintf('SELECT name FROM place where id = 1');
$result = mysql_query($query);
$result = mysql_fetch_assoc($result);


// -- Feeding UTF-8 data directly WORKS
$domDocument = new DOMDocument('1.0','UTF-8');
$rootNode = $domDocument->createElement('Response');
$rootNode->appendChild($domDocument->createCDATASection('Café Belga'));
$domDocument->appendChild($rootNode);

$matcher = array('tag' => 'Response');
self::assertTag($matcher, $domDocument->saveXML(), '', FALSE);

// -- Feeding UTF-8 data from the resultset FAILS
$domDocument = new DOMDocument('1.0','UTF-8');
$rootNode = $domDocument->createElement('Response');
$rootNode->appendChild($domDocument->createCDATASection($result['name']));
$domDocument->appendChild($rootNode);

$matcher = array('tag' => 'Response');
self::assertTag($matcher, $domDocument->saveXML(), '', FALSE);

Dans mon débogueur PHPStorm, la chaîne extraite de la base de données ressemble à ceci:

Caf� Belga

Je pense donc que c'est la racine du problème. Dans MySQLWorkbench, la chaîne est correcte: Café Belga.

Cependant, lorsque vous utilisez utf8_encode($result['name']), tout fonctionne bien!

Encore une vérification dans la fenêtre des montres:

mb_detect_encoding($result['name']) -> "UTF-8"

mb_detect_encoding(utf8_encode($result['name'])) -> "UTF-8"

Sur une note latérale, y a-t-il des sites où je peux simplement copier-coller ces valeurs hexadécimales et voir quels caractères ils sont censés être dans différents jeux de caractères?

17
Joris Mans

Vous devez définir la connexion à votre base de données comme TF-8 :

// Set up your connection
$connection = mysql_connect('localhost', 'user', 'pw');
mysql_select_db('yourdb', $connection);
mysql_query("SET NAMES 'utf8'", $connection);

// Now you get UTF-8 encoded stuff
$query = sprintf('SELECT name FROM place where id = 1');
$result = mysql_query($query, $connection);
$result = mysql_fetch_assoc($result);
50
strauberry

Depuis la version PHP 5.5.0, vous devez utiliser

mysqli_set_charset($connection,"utf8");
6
Eric Korolev