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?
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);
Depuis la version PHP 5.5.0, vous devez utiliser
mysqli_set_charset($connection,"utf8");