2011-10-22 74 views
21

我不确定何时第一次出现。数据库文本中的奇怪字符:Ã,Ã,¢,â€,

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

网站的前端包含奇怪的字符组合产品文本中:A,A,¢,Ⅰ,等它们出现在的地方像普通字符, - :等

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

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

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

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

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

如果问题与在数据库连接字符串中指定正确的语言属性一样简单,那么/如何设置此值以及该值是什么?

顺便说一句,我试图运行在phpMyAdmin此命令在this thread提及,但问题依然存在:

SET NAMES utf8 

UPDATE:PHPMyAdmin的说:

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

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

UPDATE2

这里有一个例子:

人是真正的生活untetheredÃÆ'Ã,¢Ã¢ââ,¬Å¡Ã,¬Ã¯ââ , **在线购买和租借电影,下载软件和 在网络上共享和存储文件。

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

+0

@AurelioDeRosa添加上面的示例。 – Steve

+0

我不太了解prestashop,但似乎并没有做好char编码。无论如何,我看到其他人也有同样的问题:http://www.prestashop.com/forums/topic/34545-problem-with-encoding-characters/ –

+0

是不是这只是一个有限元问题? phpMyAdmin设置为显示错误编码的东西,而客户端未设置为使用UTF-8?需要位于元标记中。 – MarianP

回答

5

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

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

你可以做的皈依以下这个文章:

+0

好的。现在看看以下内容:http://www.bluebox.net/news/2009/07/mysql_encoding – Steve

+0

请查看原始问题的更新。 – Steve

15

如果表中的字符集是一样的,因为它的内容尝试使用mysql_set_charset('UTF8', $link_identifier)。请注意,MySQL使用UTF8来指定UTF-8编码,而不是UTF-8这更常见。

检查my other answer也是如此。

+0

正如你可以在这里看到的(http://en.wikipedia.org/wiki/UTF-8),** real **的名字是UTF-8。但是,当然,在声明中可能没有短划线。 –

+0

@AurelioDeRosa我知道,但它是MySQL搞砸了:P不是我... – AlexV

+0

我知道老兄,别担心。这只是为了澄清。事实上,正如你所看到的,我声称“在声明中可能没有破折号”。最好的祝福。 –

0

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

好运

2

应用这两个东西。

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

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

1

这似乎是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编码的字符。这可以在文本编辑器中手动完成。为了帮助完成这个过程,您可以从尝试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) 
0

我今天遇到了不少类似的问题:mysqldump的甩了我的UTF-8碱基编码UTF-8变音字符作为两个latin1的字符,虽然文件本身是普通的utf8。

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

为了解决这个问题,并正确地将数据库导入到另一台服务器上,我不得不使用ftfy(代表“Fixes Text For You”)(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