Latin1 连接,而不是 UTF8
我最近收到来自使用我网站的用户的报告,他们无法用中文或阿拉伯语创建内容。这促使我尝试使用中文字符在我的网站上创建内容,我发现为这些字符存储的数据是一个问号 ?
。
我从阅读的其他问题和文章中意识到我可能处于“字符集 hell ”。
看来我一直在使用 Latin1
连接使用 Entity Framework 连接到数据库,因为这是 MySQL 的默认设置,但我数据库中的列是 UTF8
.
我的数据是如何编码的?
从我读到的过程来看,我认为我数据库中的数据是来自浏览器的 UTF8
数据,在传输到数据库的过程中编码为 Latin1
然后在存储到数据库之前再次编码为 UTF8
。
当我将连接设置为使用 UTF8
时,我一直在使用 PHP 脚本来确定数据是否正确输出 - 当我从数据库中选择数据时,它看起来并不像那里有什么区别。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<?php
//
// Make the connection to the database
//
$link = mysqli_connect('localhost','root', '', 'mydatabase');
if (!$link) {
die('Could not connect to MySQL: ' . mysql_error());
}
// Set connection character set to UTF8
$link->set_charset('utf8');
echo '<p>Connection OK</p>';
//
// Request the string from the database
//
$result = $link->query("SELECT questiontext FROM question WHERE id = 101");
$row = $result->fetch_assoc();
// Display the data
echo "Result: " . $row['questiontext'] . '<br/>';
mysqli_close($link);
?>
</body>
</html>
- 如果我使用与现有数据的
UTF8
连接请求一个看起来像 [A-Z 0-9] 字符的字符串,使用此 PHP 脚本,它会显示在屏幕上,就像在Latin1
使用 Entity Framework 时的连接,我无法区分。数据似乎没有任何问题。 - 如果我请求一串看似已作为问号输入数据库的汉字,则在通过
UTF8
连接检索时它会显示为问号。
我预计当我使用 UTF8
连接连接到数据库时,数据将显示为垃圾,因为我之前使用的是 Latin1
连接 - 但是它不是。
我使用 Entity Framework 查询在将 CharSet=utf8;
添加到我的连接字符串之前和之后用于连接的 MySql 变量。希望能让您了解连接是以前和现在是如何建立的:
之前的连接:
更新了连接字符串字符集的连接:
我如何确定数据库中的数据是否编码不正确,是否是编码为 UTF8 的 Latin1 数据,以便我可以决定是否可以只更改我的连接字符串以使用 UTF8 并且一切正常?
更新
我一直在通过在 UTF8
和 Latin1
之间切换连接类型进行试验,这些是我的发现...
如果我将连接类型设置为 latin1
并输出字符,我最终会得到如下结果:
Tu es dans une �le d�serte
HEX (bin2hex): 54752065732064616e7320756e6520 ee 6c652064 e9 7365727465203a
如果我将连接设置为 utf8
:
Tu es dans une île déserte
HEX (bin2hex): 54752065732064616e7320756e6520 c3ae 6c652064 c3a9 7365727465203a
(粗体和间距由 Rick James 添加)
当使用 UTF8 连接时,根本没有任何看起来不可靠的字符 - 仅当我将连接类型设置为 latin1
时。这让我相信我的数据编码没问题,大概是直接的 UTF8。
我只能由此破译, Entity Framework 一直在通过 UTF8 连接进行通信,但我不知道如何确认数据是否正确存储。
最佳答案
对于中文,你需要告诉MySQL使用utf8mb4,而不仅仅是utf8。
尝试使用 utf8/utf8mb4 时,如果您看到问号(常规问号,不是黑色菱形)(?
是十六进制 3F
),
- 要存储的字节未编码为 utf8。解决这个问题。
- 数据库中的列是
CHARACTER SET utf8mb4
.解决这个问题。 - 另外,检查读取时的连接是否为utf8mb4。
新浪新闻
是 新浪新闻
的 Mojibake
尝试使用 utf8/utf8mb4 时,如果看到 Mojibake,请检查以下内容。 此讨论也适用于不一定可见的双重编码。
- 要存储的字节需要进行utf8编码。
INSERTing
时的连接和SELECTing
文本需要指定utf8mb4。 (set_charset
)- 列需要声明
CHARACTER SET utf8mb4
. (与SHOW CREATE TABLE
联系。) - HTML 应以
<meta charset=UTF-8>
开头. (你做到了。)
要验证,执行SELECT col, HEX(col) FROM ...
.如果 新
的十六进制输出是E696B0
, 然后它被正确编码为 utf8/utf8mb4。如果你得到 C3A6E28093C2B0
,它是“双重编码”的。 通常 如果十六进制以 E 或 F 开头,则它可能已正确编码。此外,在所有情况下,单个汉字的十六进制长度均为 6 或 8。 Reference .
关于php - 从 Latin1 连接存储的 UTF8 数据,如何检查我的数据是否正常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38353283/