我从各种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;
}

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


当前回答

从头文件中获取编码并将其转换为UTF-8。

$post_url = 'http://website.domain';

/// Get headers ///////////////////////////////////////////////
function get_headers_curl($url)
{
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL,            $url);
    curl_setopt($ch, CURLOPT_HEADER,         true);
    curl_setopt($ch, CURLOPT_NOBODY,         true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT,        15);

    $r = curl_exec($ch);
    return $r;
}

$the_header = get_headers_curl($post_url);

/// Check for redirect ////////////////////////////////////////
if (preg_match("/Location:/i", $the_header)) {
    $arr = explode('Location:', $the_header);
    $location = $arr[1];

    $location = explode(chr(10), $location);
    $location = $location[0];

    $the_header = get_headers_curl(trim($location));
}

/// Get charset ///////////////////////////////////////////////
if (preg_match("/charset=/i", $the_header)) {
    $arr = explode('charset=', $the_header);
    $charset = $arr[1];

    $charset = explode(chr(10), $charset);
    $charset = $charset[0];
}

///////////////////////////////////////////////////////////////////
// echo $charset;

if($charset && $charset != 'UTF-8') {
    $html = iconv($charset, "UTF-8", $html);
}

其他回答

if(!mb_check_encoding($str)){
    $str = iconv("windows-1251", "UTF-8", $str);
}

这对我很有帮助

整理完PHP脚本后,不要忘记告诉MySQL你要传递的字符集和你想要接收的字符集。

例如:设置为UTF-8

在Latin 1 I/O会话中将UTF-8数据传递给Latin 1表会导致这些讨厌的鸟脚。我每隔一天就会在OsCommerce商店看到这个。后面和第四个似乎是对的。但是phpMyAdmin会显示真相。通过告诉MySQL你正在传递什么字符集,它将为你处理MySQL数据的转换。

如何恢复现有的乱码MySQL数据是另一个问题。:)

你的编码看起来像是用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)。

不带auto的Try

那就是:

mb_detect_encoding($text)

而不是:

mb_detect_encoding($text, 'auto')

更多信息可以在这里找到:mb_detect_encoding

一个实现isutf8函数的好方法可以在php.net上找到:

function isUTF8($string) {
    return (utf8_encode(utf8_decode($string)) == $string);
}