34

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

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

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

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

另一个网站线程,当数据库连接字符串使用不正确的字符编码类型时,也会出现同样的问题

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

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

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

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

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

SET NAMES utf8

更新: PHPMyAdmin 说:

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

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

更新2

这是一个示例:

人们真正生活在无拘无束的环境中——在线购买和租借电影、下载软件、共享和存储文件网络。

更新3

我在 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 小时内没有回复。对他们来说可能太难了。

4

6 回答 6

20

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

检查我对类似问题的其他答案。

于 2011-10-25T12:59:54.333 回答
5

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

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

您可以按照本文进行转换:

于 2011-10-22T12:02:11.580 回答
4

这似乎是一个 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 编码一次)

试图在 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å");

在这种情况下,另一个很好且可能的解决方案也会静默失败

$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)

尝试通过将 MySQL 数据库字符集和排序规则转换为 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)
于 2016-02-12T17:05:12.090 回答
3

我今天遇到了一个非常相似的问题: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
于 2017-07-25T17:59:28.800 回答
2

应用这两件事。

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

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

于 2014-09-09T12:32:08.043 回答
1

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

祝你好运

于 2014-06-12T10:18:47.737 回答