我从各种RSS订阅中阅读大量文本,并将它们插入到我的数据库中。

当然,在提要中使用了几种不同的字符编码,例如UTF-8和ISO 8859-1。

不幸的是,文本的编码有时会有问题。例子:

“Fußball”中的“ß”在我的数据库中应该是这样的:“Ÿ”。如果是“Ÿ”,则显示正确。 有时,“Fußball”中的“ß”在我的数据库中看起来像这样:“ß”。当然,这样就会显示错误。 在其他情况下,“ß”被保存为“ß”-因此没有任何变化。然后它也会被错误地显示。

我怎么做才能避免情况2和3?

我如何使所有的编码相同,最好是UTF-8?什么时候我必须使用utf8_encode(),什么时候我必须使用utf8_decode()(很清楚的效果是什么,但什么时候我必须使用函数?),什么时候我必须对输入什么都不做?

如何让所有编码都相同呢?也许使用函数mb_detect_encoding()?我能写一个函数吗?所以我的问题是:

如何找出文本使用的编码? 我如何将其转换为UTF-8 -无论旧的编码是什么?

这样的函数可行吗?

function correct_encoding($text) {
    $current_encoding = mb_detect_encoding($text, 'auto');
    $text = iconv($current_encoding, 'UTF-8', $text);
    return $text;
}

我已经测试过了,但是不行。有什么问题吗?


当前回答

我在phpQuery (ISO-8859-1而不是UTF-8)上也有同样的问题,这个hack帮助了我:

$html = '<?xml version="1.0" encoding="UTF-8" ?>' . $html;

mb_internal_encoding('UTF-8'), phpQuery::newDocumentHTML($html, 'UTF-8'), mbstring.internal_encoding和其他操作没有起任何作用。

其他回答

我一直在寻找编码的解决方案,这个页面可能是多年搜索的结论!我测试了你提到的一些建议,以下是我的笔记:

这是我的测试字符串:

这是一个“wròng wrìtten”字符串bùt I nèed到pù‘sòme’的特殊 Chàrs看thèm, convertèd看fùnctìon!!&就是这样!

我执行INSERT操作将该字符串保存在数据库中的字段中,该字段设置为utf8_general_ci

我的页面的字符集是UTF-8。

如果我像这样做一个INSERT,在我的数据库中,我有一些字符可能来自火星…

所以我需要把它们转换成一些“理智的”UTF-8。我尝试utf8_encode(),但仍然外星人字符入侵我的数据库…

所以我尝试使用函数forceeutf8张贴在数字8,但在数据库中保存的字符串看起来像这样:

这是一个“wròng wrà tten”的字符串bùt I nèed to pù'sòme'特殊 Chà rs看thèm, convertèd由fùnctà on!!&就是这样!

所以在这个页面上收集更多的信息,并将它们与其他页面上的其他信息合并,我用这个解决方案解决了我的问题:

$finallyIDidIt = mb_convert_encoding(
  $string,
  mysql_client_encoding($resourceID),
  mb_detect_encoding($string)
);

现在在我的数据库中,我有了编码正确的字符串。

注意:

唯一需要注意的是mysql_client_encoding函数! 您需要连接到数据库,因为这个函数需要一个资源ID作为参数。

但是,我只是在插入之前重新编码,所以对我来说这不是问题。

哈帕克斯的回答对我很管用。对我来说,这就足够了:

if (isUTF8($str)) {
    echo $str;
}
else
{
    echo iconv("ISO-8859-1", "UTF-8//TRANSLIT", $str);
}

你的编码看起来像是用UTF-8编码了两次;也就是说,从其他编码,转换成UTF-8,再转换成UTF-8。就好像您有ISO 8859-1,从ISO 8859-1转换为UTF-8,并将新字符串处理为ISO 8859-1,以便再次转换为UTF-8。

下面是你所做的一些伪代码:

$inputstring = getFromUser();
$utf8string = iconv($current_encoding, 'utf-8', $inputstring);
$flawedstring = iconv($current_encoding, 'utf-8', $utf8string);

你应该试试:

使用mb_detect_encoding()或任何您喜欢使用的方法来检测编码 如果是UTF-8,转换成ISO 8859-1,然后重复步骤1 最后,转换回UTF-8

这是假设在“中间”转换中使用ISO 8859-1。如果您使用的是Windows-1252,则转换为Windows-1252 (latin1)。原始源编码并不重要;你在有缺陷的第二次转换中使用的是。

以下是我对所发生事情的猜测;要用四个字节代替一个扩展的ASCII字节,您几乎没有其他办法。

德语也使用ISO 8859-2和Windows-1250(拉丁语-2)。

这很简单:当您得到一些不是UTF-8的东西时,您必须将其编码为UTF-8。

因此,当你获取某个ISO 8859-1的提要时,通过utf8_encode解析它。

但是,如果您正在获取UTF-8提要,则不需要做任何事情。

提醒一下。您说在您的数据库中“ß”应该显示为“Ÿ”。

这可能是因为你正在使用一个Latin-1字符编码的数据库,或者你的PHP-MySQL连接设置错误,也就是说,P认为你的MySQL设置为使用UTF-8,所以它发送数据为UTF-8,但你的MySQL认为PHP发送的数据编码为ISO 8859-1,所以它可能再次尝试将你发送的数据编码为UTF-8,造成这种麻烦。

看一下mysql_set_charset。它可能对你有帮助。