Я использую PHPUnit для проверки вывода XML из моего PHP-кода, но, видимо, у меня возникают проблемы с кодировкой символов MySQL. Вот ошибка, которую я получаю из DOMDocument:
Input is not proper UTF-8, indicate encoding!
Bytes: 0xE9 0x20 0x42 0x65
Я инициализирую DOMDocument, чтобы он использовал правильную кодировку:
$domDocument = new DOMDocument('1.0','UTF-8');
И когда я проверяю вывод из saveXML(), используя mb_detect_encoding, результат UTF-8.
Я также проверил все вызовы, используемые для создания XML, используя mb_detect_encoding для всех созданных параметров createCDATASection, и все они либо UTF- 8, либо ASCII (нет обычных текстовых узлов, все в CDATA).
Я думаю, проблема связана с использованием символа 'é' (который равен 0xE9 в ISO 8859- 1). Строка, которая добавляет этот символ в мой XML:
$domDocument->createCDATASection($place->name);
и mb_detect_encoding ($place- > name) дает мне UTF- 8.
Данные ($place- > name) извлекаются из базы данных MySQL. Эта база данных имеет кодировку UTF- 8.
Вот пример кода:
$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);
В моем отладчике PHPStorm строка, извлеченная из базы данных, выглядит так:
Caf Belga
Итак, я думаю, что это корень проблемы. В MySQLWorkbench строка верна: Café Belga.
При использовании utf8_encode($result['name'])
все работает нормально!
Еще одна проверка в окне часов:
mb_detect_encoding($result['name'])
→ "UTF- 8"
mb_detect_encoding(utf8_encode($result['name']))
→ "UTF- 8"
На стороне примечания, есть ли какие-либо сайты, где я могу просто copy- вставить эти шестнадцатеричные значения и посмотреть, какие символы они должны быть в разных наборах символов?