为什么iconv会产生非法字符错误?

时间:2012-09-21 10:06:37

标签: php php-5.2

我正试图从剧本中删除警告和通知。该脚本包括以下内容:

$clean_string = iconv('UTF-8', 'UTF-8//IGNORE', $supplier.' => '.$product_name);

据我了解,该行的目的是按照脚本的原作者的意图,从字符串中删除非UTF-8字符,但显然输入中的任何非UTF-8字符都将导致iconv抛出非法字符警告。

要解决这个问题,我的想法是做以下事情:

$clean_string = iconv(mb_detect_encoding($supplier.' => '.$product_name), 'UTF-8//IGNORE', $supplier.' => '.$product_name);

然而奇怪的是,mb_detect_encoding()返回UTF-8作为检测到的编码!

带有重音(é)的字母e是导致此行为的字符示例。

我意识到我在检测和转换之间混合使用多字节库,但我在iconv库中找不到编码检测功能。

我考虑过使用mb_convert_encoding()函数将字符串清理成UTF-8,但PHP文档并不清楚无法表示的字符会发生什么。

我使用PHP 5.2.17,并使用glibc iconv实现,库版本2.5。

任何人都可以提供有关如何将字符串清理为UTF-8的任何建议,或者了解为什么会出现这种情况?

1 个答案:

答案 0 :(得分:3)

你的例子:

$string     = $supplier . ' => ' . $product_name;
$stringUtf8 = iconv('UTF-8', 'UTF-8//IGNORE', $string);

并使用PHP 5.2可能适合您。在以后的PHP版本中,如果输入不是精确的UTF-8,incov将丢弃该字符串(您将获得一个空字符串)。到目前为止,你可能没有注意到它。

然后您尝试使用mb_detect_encoding­Docs查找原始编码:

$string     = $supplier . ' => ' . $product_name;
$encoding   = mb_detect_encoding($string);
$stringUtf8 = iconv($encoding, 'UTF-8//IGNORE', $string);

正如我已经在评论中链接的那样,mb_detect_encoding正在做一些魔术而无法奏效。它会尝试帮助您,但无法检测到编码非常好。这是主题的问题。您可以尝试将严格模式设置为true:

$order      = mb_detect_order();
$encoding   = mb_detect_encoding($string, $order, true);
if (FALSE === $encoding) {
    throw new UnexpectedValueException(
        sprintf(
            'Unable to detect input encoding with mb_detect_encoding, order was: %s'
            , print_r($order, true)
        )
     );
}

除此之外,您可能还需要在两个库(iconv和多字节字符串)之间翻译the names of the encoding­Docs(和/或验证支持的编码)。

希望这有帮助,这样你至少可以更好地理解为什么有些东西可能不起作用,以及如何更好地找到错误案例并使用标准的PHP扩展来过滤输入。