时间:2011-10-22 09:44:29

标签: database character-encoding prestashop

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

我有一个新的drop-shipping会员网站,并从批发商那里收到产品目录的导出副本。我格式化并将其导入Prestashop 1.4.4。

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

这些字符存在于大约40%的数据库表中,而不仅仅是产品特定的表,如ps_product_lang。

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

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

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

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

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

我很自然地尝试在this thread中提到的PHPMyAdmin中运行此命令,但问题仍然存在:

SET NAMES utf8

更新:PHPMyAdmin说:

  

MySQL charset:UTF-8 Unicode(utf8)

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

UPDATE2

以下是一个示例:

  

人们真正生活在不受干扰的地方,••••••†  Ã,ï†在线购买和租借电影,下载软件和   在网络上共享和存储文件。

UPDATE3

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

  • character_set_client utf8
  • character_set_connection utf8
  • character_set_database latin1
  • character_set_filesystem binary
  • character_set_results utf8
  • character_set_server latin1
  • character_set_system utf8

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

MySQL能否将服务内容的翻译处理为UTF8,但将其存储为latin1?我不认为它可以,因为UTF8是latin1的超集。我的网络托管支持在48小时内没有回复。对他们来说可能太难了。

6 个答案:

答案 0 :(得分:16)

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

同样检查my other answer类似问题。

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:2)

应用这两件事。

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

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

答案 3 :(得分:2)

这似乎是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()失败并显示“Notice: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)

答案 4 :(得分:1)

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

祝你好运

答案 5 :(得分:1)

我今天遇到了类似的问题: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