2011-06-03 20 views
13

我使用PHPUnit来验证来自我的PHP代码的XML输出,但显然我有字符编码MySQL返回的问题。下面是我从DOM文档时出现错误:如何让MySQL返回UTF-8?

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

我初始化DOM文档,因此使用正确的编码:

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

当我使用检查从saveXML()的输出mb_detect_encoding结果是UTF-8

我还检查了所有用于创建XML的调用,在遇到的所有createCDATASection参数上使用mb_detect_encoding,它们都是UTF-8或ASCII(没有纯文本节点,所有内容都在CDATA块中)。

我认为这个问题来自使用'é'字符(在ISO 8859-1中是0xE9)。它补充说,性格我的XML的行是:

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

和mb_detect_encoding($地方 - >名)给了我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调试器,将字符串从数据库中获取如下:

咖啡馆贝尔加

所以我觉得这是问题的根源。在MySQLWorkbench中,字符串是正确的:CaféBelga。

使用utf8_encode($result['name'])时,一切正常!

还有一个检查在钟表窗口:

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

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

在一个侧面说明,是否有任何网站,我可以简单地复制粘贴这些十六进制值,并查看它们应该在不同的字符集中使用哪些字符?

+0

凡存储在 'E' 字?在一个文件中?在你的代码中? – Yeroon 2011-06-03 09:24:49

+0

糟糕,忘了提及这一点,我编辑了我的问题:数据是从MySQL数据库中提取的。这个数据库有utf8字符集。 – 2011-06-03 09:27:01

+0

@Joris是否在创建domdocument之后的任何时候使用loadXml?另外,您能否为我们提供可再现的测试用例来说明问题? – Gordon 2011-06-03 09:33:51

回答

42

你必须定义为UTF-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); 
+0

谢谢!这解决了它! – 2011-06-03 13:09:20

+0

很高兴我能帮忙:-) – strauberry 2011-06-03 14:32:47

+0

你不应该使用'SET NAMES'(参见http://stackoverflow.com/questions/5288953/is-mysql-real-escape-string-broken/5289141#5289141)。 – Gumbo 2011-06-03 17:38:19

0

自PHP 5.5.0你应该使用

mysqli_set_charset($connection,"utf8");