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

标签 php mysql character-encoding entity-framework-6 utf8mb4

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 变量。希望能让您了解连接以前和现在是如何建立的:

之前的连接:

Connection before

更新了连接字符串字符集的连接:

Connection after connection string update

我如何确定数据库中的数据是否编码不正确,是否是编码为 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编码。
  • 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/

相关文章:

php - 如何检查是否在同一页面中使用php单击了提交按钮

php - 如何在 MySQL 数据库中存储苗族字符

执行 SELECT 时的 MySQL 特殊字符显示其他没有特殊字符的结果

php - MySQL int 列允许 null 但将 null 输入为零

php - 使用 php(或可能是其他东西;又名 AJAX)验证表单的正确方法

php - Laravel 5 Seeder - 数据库中的多行

php - 使用不同数量的搜索关键字在数据库中搜索客户

html - 如何将 default.html 的字符编码设置为 UTF-8?

php - mysql插入错误检查

php - 多个文件输入实现