从 Latin1 连接存储的 UTF8 数据,如何检查我的数据是否正常?

UTF8 data stored from a Latin1 Connection, how to check if my data is OK?

Latin1 连接,而不是 UTF8

我最近收到来自使用我网站的用户的报告,他们无法创建中文或阿拉伯语的内容。这促使我尝试使用中文字符在我的网站上创建内容,我发现为这些字符存储的数据是一个问号 ?.

我从我读过的其他问题和文章中意识到 我可能在 'character set hell'.

我似乎一直在使用 Entity Framework 连接到数据库,使用 Latin1 连接,因为这是 MySQL 的默认设置,但我数据库中的列是UTF8.

我的数据是如何编码的?

从我读到的过程来看,我认为我数据库中的数据是来自浏览器的 UTF8 数据,在传输到数据库的过程中编码为 Latin1 然后再次编码作为 UTF8 就在它存储在数据库中之前。

我一直在使用 PHP 脚本来确定当我将连接设置为使用 UTF8 时数据是否正确输出 - 当我从数据库中 select 数据时,看起来没有什么区别。

  <!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 连接连接到数据库时,数据将显示为垃圾,因为我之前使用的是 Latin1 连接 - 但事实并非如此.

我使用 Entity Framework 来查询在将 CharSet=utf8; 添加到我的连接字符串之前和之后用于连接的 MySql 变量。希望可以让您了解连接 是如何建立的 之前以及现在如何:

之前的连接:

连接字符串字符集已更新:

我如何确定数据库中的数据是否编码不正确,它是否是编码为 UTF8 的 Latin1 数据,以便我可以决定是否可以将我的连接字符串更改为使用 UTF8 并且一切正常?

更新

我一直在尝试在 UTF8Latin1 之间切换连接类型,这些是我的发现...

如果我将我的连接类型设置为 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编码。
  • INSERTingSELECTing文本时的连接需要指定utf8mb4。 (set_charset)
  • 列需要声明 CHARACTER SET utf8mb4。 (检查 SHOW CREATE TABLE。)
  • HTML 应该以 <meta charset=UTF-8> 开头。 (你做到了。)

验证,请执行SELECT col, HEX(col) FROM ...。如果 的十六进制输出是 E696B0,那么它被正确编码为 utf8/utf8mb4。如果得到C3A6E28093C2B0,就是"double-encoded"。 通常 如果十六进制以 E 或 F 开头,则它可能已正确编码。此外,在所有情况下,单个汉字的十六进制长度均为 6 或 8。 Reference.

尝试使用这个:

//显示数据 回声 "Result: " 。 utf8_encode($行['questiontext']) 。 '
';

;)

申请->mysql:select HEX('中国')
mysql->申请:select UNHEX('E4B8ADE59BBD') 您可以使用 MySQL 函数