如何让 MySQL 返回 UTF-8?

Posted

技术标签:

【中文标题】如何让 MySQL 返回 UTF-8?【英文标题】:How do I make MySQL return UTF-8? 【发布时间】:2011-09-07 16:12:54 【问题描述】:

我正在使用 phpUnit 来验证我的 PHP 代码的 XML 输出,但显然我遇到了字符编码 mysql 返回的问题。这是我从 DOMDocument 得到的错误:

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

我初始化 DOMDocument 以便它使用正确的编码:

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

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

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

我认为问题出在使用“é”字符(ISO 8859-1 中的 0xE9)。将该字符添加到我的 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"

顺便说一句,是否有任何网站可以让我简单地复制粘贴这些十六进制值并查看它们在不同字符集中应该包含哪些字符?

【问题讨论】:

'é' 字符存储在哪里?在一个文件中?在你的代码中? 哎呀,忘了提这个,我编辑了我的问题:数据是从 mysql 数据库中提取的。此数据库具有 utf8 字符集。 @Joris 您在创建 domdocument 后的任何时候都使用 loadXml 吗?另外,您能否为我们提供一个可重现的测试用例来说明问题? 没有使用 loadXml 编号。我会尝试做一个测试用例 连接mysql后尝试添加mysql_set_charset('utf-8'); 【参考方案1】:

您必须将与数据库的连接定义为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);

【讨论】:

你不应该使用SET NAMES(见***.com/questions/5288953/…)。 感谢您的提示,Gubmo!不知道【参考方案2】:

你应该使用 PHP 5.5.0 版本

mysqli_set_charset($connection,"utf8");

【讨论】:

并以面向对象的方式,即:$connection->set_charset("utf8mb4");

以上是关于如何让 MySQL 返回 UTF-8?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 docker compose 使用 utf-8 设置 mysql?

如何在 MySQL 中控制 UTF-8 排序?

Promise mysql返回未定义,如何让函数等待结果

如何让返回等待 MySQL 连接结束?节点.js

如何让 mySql 返回 Select JOIN with Count?

如何让 mysql 与标签搜索一起获得平均评分?