【问题标题】:Strange Characters in database text: Ã, Ã, ¢, â‚ €,数据库文本中的奇怪字符:Ã、Ã、¢、â‚ €、
【发布时间】:2011-12-13 06:22:14
【问题描述】:

我不确定这是什么时候发生的。

我有一个新的直销联属网络营销网站,并从批发商那里收到一份导出的产品目录副本。我将其格式化并导入 Prestashop 1.4.4。

网站的前端在产品文本中包含奇怪字符的组合:Ã、Ã、¢、â‚ 等。它们代替常见的字符(如 、- : 等)出现。 p>

这些字符出现在大约 40% 的数据库表中,而不仅仅是像 ps_product_lang 这样的产品特定表。

Another website thread当数据库连接字符串使用不正确的字符编码类型时也会出现同样的问题

在 /config/setting.inc 中,没有提到字符编码字符串,只是 MySQL 引擎,它设置为 InnoDB,与我在 PHPMyAdmin 中看到的匹配。

我导出了 ps_product_lang,将这些字符的所有实例替换为正确的字符,将 CSV 文件保存为 UTF-8 格式,然后使用 PHPMyAdmin 重新导入它们,指定 UTF-8 作为语言。

但是,在 PHPMyAdmin 中进行新搜索后,我现在在 ps_product_lang 中的这些坏字符的实例数量大约是我开始时的 10 倍。

如果问题就像在数据库连接字符串中指定正确的语言属性一样简单,我在哪里/如何设置它,以及如何设置?

顺便说一句,我尝试在this thread中提到的PHPMyAdmin中运行此命令,但问题仍然存在:

SET NAMES utf8

更新:PHPMyAdmin 说:

MySQL 字符集:UTF-8 Unicode (utf8)

这是我在上次导入文件中使用的相同字符集,导致更多字符损坏。在导入过程中将 UTF-8 指定为导入文件的字符集。

更新2

这是一个示例:

人们真正生活在无拘无束的生活中。 ‚ï† 在线购买和租借电影、下载软件,以及 在网络上共享和存储文件。

UPDATE3

我在 PHPMyAdmin 中运行了一条 SQL 命令来显示字符集:

  • character_set_client utf8
  • character_set_connection utf8
  • character_set_database latin1
  • character_set_filesystem 二进制文件
  • character_set_results utf8
  • character_set_server latin1
  • character_set_system utf8

所以,也许我的数据库需要转换(或删除并重新创建)为 UTF-8。如果 MySQL 服务器是 latin1,这会造成问题吗?

MySQL 是否可以将服务内容转换为 UTF8 但将其存储为 latin1?我不认为它可以,因为 UTF8 是 latin1 的超集。我的虚拟主机支持在 48 小时内没有回复。对他们来说可能太难了。

【问题讨论】:

  • @AurelioDeRosa 上面添加的示例。
  • 我对 prestashop 了解不多,但似乎它没有很好的 char 编码。无论如何,我看到其他人也有同样的问题:prestashop.com/forums/topic/…
  • 这不只是一个FE问题吗? phpMyAdmin 设置为以错误的编码显示内容,而客户端未设置为使用 UTF-8?需要在元标记中。
  • @MarianP 数据库和服务器是 latin1 而 PHPMyAdmin 和 CSV 是 UTF8。 (见上面的更新3)
  • 您无需重置所有数据库即可尝试。只需从 CSV 中获取“脏”行,将 utf-8 转换为 latin1 并将该行插入数据库。如果换行符正确,则问题已解决。

标签: database character-encoding prestashop


【解决方案1】:

这肯定是一个编码问题。您的数据库和网站中有不同的编码,这就是问题的原因。此外,如果您运行该命令,则必须更改表中已有的记录以将这些字符转换为 UTF-8。

更新:根据您最后的评论,问题的核心是您有一个使用不同编码的数据库和一个数据源(CSV 文件)。因此,您可以将数据库转换为 UTF-8,或者至少,当您获取 CSV 中的数据时,您必须将它们从 UTF-8 转换为 latin1。

您可以按照这篇文章进行转换:

【讨论】:

【解决方案2】:

如果表格的字符集与其内容相同,请尝试使用mysql_set_charset('UTF8', $link_identifier)。请注意,MySQL 使用 UTF8 来指定 UTF-8 编码,而不是更常见的 UTF-8

检查my other answer 也有类似的问题。

【讨论】:

  • 正如您在此处看到的 (en.wikipedia.org/wiki/UTF-8),真正的名称是 UTF-8。但是,当然,在声明中可能没有破折号。
  • 我知道伙计,别担心。这只是为了澄清。事实上,正如你所看到的,我断言“声明中可能没有破折号”。最好的问候。
  • @AlexV:我在 PrestaShop 中使用它吗?如果有,你知道怎么做吗?
  • @Steve 默认应该是内置的。我查看了 PrestaShop 代码库,他们不使用 mysql_set_charset。所以我猜他们要么使用默认表字符集,要么即时转换数据。我猜表格的内容与表格的字符集不匹配。
  • 我可以从 Ã 判断这是正确的答案。这些是 db 存储为单个字符的 2 字节序列中的第一个,因为它期待 latin1
【解决方案3】:

该错误通常是在创建 CSV 时引入的。尝试使用 Linux 将 CSV 保存为 TextCSV。 Ubuntu 中的 Libre Office 可以强制编码为 UTF-8,对我有用。 我浪费了很多时间在 Mac OS 上尝试这个。 Linux 是关键。我在 Ubuntu 上测试过。

祝你好运

【讨论】:

    【解决方案4】:

    应用这两件事。

    1. 您需要将数据库的字符集设置为utf8

    2. 您需要在与数据库建立连接的文件中调用mysql_set_charset('utf8'),并在选择mysql_select_db等数据库后立即使用mysql_set_charset。这将允许您以任何语言正确添加和检索数据。

    【讨论】:

      【解决方案5】:

      这似乎是一个 UTF-8 编码问题,可能是由数据库文件内容的双 UTF8 编码引起的。

      这种情况可能是由于选择或未选择的字符集(例如创建数据库备份文件时)以及保存的文件格式和编码数据库文件等因素造成的。

      我在以下场景中看到了这些奇怪的 UTF-8 字符(描述可能不完全准确,因为我不再有权访问相关数据库):

      • 我记得,那里的数据库和表有一个“uft8_general_ci”排序规则。
      • 对数据库进行备份。
      • 备份文件在 Windows 上以 UNIX 文件格式和 ANSI 编码打开。
      • 通过将数据库备份文件中的内容复制粘贴到 phpMyAdmin 中,在新的 MySQL 服务器上恢复数据库。

      查看文件内容:

      • 在文本编辑器中打开 SQL 备份文件显示 SQL 备份文件有奇怪的字符,例如“sÃ¥”。附带说明一下,如果在另一个编辑器中打开同一个文件,您可能会得到不同的结果。我在这里使用 TextPad,但在 SublimeText 中打开同一个文件时说“sÃ¥”,因为 SublimeText 正确地对文件进行了 UTF8 编码——尽管如此,当您开始尝试在 PHP 中解决问题时,这有点令人困惑,因为您没有看到首先在 SublimeText 中正确的数据。无论如何,这可以通过记下您的文本编辑器在呈现文件内容时使用的编码来解决。
      • 奇怪的字符是双重编码的 UTF-8 字符,所以在我的例子中,第一个“Ô部分等于“Ô和“Â¥”=“¥”(这是我的第一个“编码”)。 “Ã¥”字符等于“å”的 UTF-8 字符(这是我的第二个编码)。

      所以,问题是“假”(UTF8 编码两次)utf-8 需要转换回“正确”utf-8(仅 UTF8 编码一次)。。 p>

      尝试在 PHP 中解决这个问题有点困难:

      utf8_decode() 无法处理字符。

      // Fails silently (as in - nothing is output)
      $str = "så";
      
      $str = utf8_decode($str);
      printf("\n%s", $str);
      
      $str = utf8_decode($str);
      printf("\n%s", $str);
      

      iconv() 失败并显示“注意:iconv():检测到输入字符串中的非法字符”。

      echo iconv("UTF-8", "ISO-8859-1", "så");
      

      另一个fine and possible solution 在这种情况下也静默失败

      $str = "så";
      echo html_entity_decode(htmlentities($str, ENT_QUOTES, 'UTF-8'), ENT_QUOTES , 'ISO-8859-15');
      

      mb_convert_encoding() 静默:#

      $str = "så";
      echo mb_convert_encoding($str, 'ISO-8859-15', 'UTF-8');
      // (No output)
      

      尝试通过converting the MySQL database characterset and collation to UTF-8修复MySQL中的编码不成功:

      ALTER DATABASE myDatabase CHARACTER SET utf8 COLLATE utf8_unicode_ci;
      ALTER TABLE myTable CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
      

      我看到了几种解决此问题的方法。

      首先是使用正确的编码进行备份(编码需要与实际的数据库和表编码匹配)。您只需在文本编辑器中打开生成的 SQL 文件即可验证编码。

      另一种是将双UTF8编码的字符替换为单UTF8编码的字符。这可以在文本编辑器中手动完成。为协助完成此过程,您可以手动从 Try UTF-8 Encoding Debugging Chart 中挑选不正确的字符(这可能是替换 5-10 个错误的问题)。

      最后,一个脚本可以帮助完成这个过程:

          $str = "så";
          // The two arrays can also be generated by double-encoding values in the first array and single-encoding values in the second array.
          $str = str_replace(["Ã","Â¥"], ["Ã","¥"], $str); 
          $str = utf8_decode($str);
          echo $str;
          // Output: "så" (correct)
      

      【讨论】:

        【解决方案6】:

        我今天遇到了一个非常相似的问题:mysqldump 将我的 utf-8 基本编码 utf-8 变音字符转储为两个 latin1 字符,尽管文件本身是常规的 utf8。

        例如:“é”被编码为两个字符“é”。这两个字符对应于字母的 utf8 两字节编码,但应将其解释为单个字符。

        为了解决问题并在另一台服务器上正确导入数据库,我必须使用 ftfy(代表“为您修复文本”)转换文件。(https://github.com/LuminosoInsight/python-ftfy)python 库。该库完全符合我的预期: 将错误编码的 utf-8 转换为正确编码的 utf-8。

        例如:这个 latin1 组合“é”变成了“é”。

        ftfy 带有一个命令行脚本,但它会转换文件,因此无法将其导入回 mysql。

        我写了一个 python3 脚本来解决这个问题:

        #!/usr/bin/python3
        # coding: utf-8
        
        import ftfy
        
        # Set input_file
        input_file = open('mysql.utf8.bad.dump', 'r', encoding="utf-8")
        # Set output file
        output_file = open ('mysql.utf8.good.dump', 'w')
        
        # Create fixed output stream
        stream = ftfy.fix_file(
            input_file,
            encoding=None,
            fix_entities='auto', 
            remove_terminal_escapes=False, 
            fix_encoding=True, 
            fix_latin_ligatures=False, 
            fix_character_width=False, 
            uncurl_quotes=False, 
            fix_line_breaks=False, 
            fix_surrogates=False, 
            remove_control_chars=False, 
            remove_bom=False, 
            normalization='NFC'
        )
        
        # Save stream to output file
        stream_iterator = iter(stream)
        while stream_iterator:
            try:
                line = next(stream_iterator)
                output_file.write(line)
            except StopIteration:
                break
        

        【讨论】:

        • 此脚本失败,出现“UnicodeEncodeError: 'charmap' codec can't encode characters in position 271-272: character maps to ” on char Å¡
        猜你喜欢
        • 2021-03-26
        • 1970-01-01
        • 1970-01-01
        • 2013-06-15
        • 1970-01-01
        • 1970-01-01
        • 2014-07-25
        • 2011-09-30
        相关资源
        最近更新 更多