【问题标题】:Can't reproduce "iconv(): Detected an illegal character in input string", but I keep getting on server无法重现“iconv():在输入字符串中检测到非法字符”,但我一直在服务器上
【发布时间】:2021-05-09 00:37:32
【问题描述】:

对于用户代理和图像 EXIF 数据,我的系统尝试使用 iconv() 转换任何 UTF-8 字符。

但是,有时我会收到以下错误:

PHP 警告 [8]: iconv(): 检测到输入字符串中的非法字符

例如:

iconv('UTF-8', 'ASCII//TRANSLIT', 'Mozilla/5.0 (iPhone; CPU OS 10_15_5 (Ergänzendes Update) like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 Mobile/14E304 Safari/605.1.15');

iconv('UTF-8', 'ASCII//TRANSLIT', 'Ïðîãðàììà öèôðîâîé îáðàáîòêè èçîáðàæåíèé êîìïàíèè ACD Systems');

结果变成了一个空字符串。

但是,当我复制上述内容并手动运行(在同一台服务器上)时,它可以工作...我没有收到任何错误,并且字符转换为“?”。

多年来我一直在尝试许多不同的东西,例如不同的编码,使用“IGNORE”而不是“TRANSLIT”,使用mb_convert_encoding,等等...
但是,如果我无法捕获导致问题的真实输入,并且我不知道我能做些什么来“修复”这个问题,那么调试/修复这个真的很难。

我该怎么做,以便将whatever输入提供给iconv(),任何非ASCII字符都将被转换为问号,而不会失败?

【问题讨论】:

  • 您想要 1960 年的 7 位 ASCII,还是想要特定的 8 位 ASCII,例如 ISO-8859-1?对于其他有帮助的人,请尝试将$s = "\u{2021}"iconv('UTF-8', 'ASCII//TRANSLIT', $s) 一起使用,这对我来说会抛出。对于 OP,我不认为 //TRANSLIT 保证 ?,只是会发生“类似的事情,取决于操作系统”。当我通过mb_convert_encoding($s, 'ASCII') 运行我的示例字符串时,它似乎是正确的并且永远不会抛出。

标签: php apache utf-8 iconv php-7.4


【解决方案1】:

早上好, 我的问题仍然存在,因为 iconv 无法识别某些字符。我尝试了来自不同组的几个代码选项,但实际工作如下:

//注意:Conversor de caracteres para UTF8

 public function ConvertToUTF8($text)
{
    $encoding = mb_detect_encoding($text.'x', mb_detect_order(), false);
    if($encoding == "UTF-8")
    {
        //Converte letra a letra
        $i    = 0;
        $conv = '';
        do 
        {
            $letra = substr($text,$i,1);
            $conv .= iconv(mb_detect_encoding($letra, mb_detect_order(), true), "UTF-8//IGNORE", $letra);
            $i ++;
        } while ($i < strlen($text) );
        $text = $conv;
    }
    else if ($encoding == 'ISO-8859-1')
    {
        $text = mb_convert_encoding($text, 'ISO-8859-1', 'UTF-8');
    }
    else if ($encoding == 'ASCII')
    {
        $text = mb_convert_encoding($text, "UTF-8");
    }
    $out = iconv(mb_detect_encoding($text.'x', mb_detect_order(), false), "UTF-8//TRANSLIT//IGNORE", $text);

    return $out;
}//Fim Módulo

【讨论】:

    【解决方案2】:

    非法 UTF 字符很容易因错误而产生。一个例子:

    $currencies='€$';
    $str = "äöü|".substr($currencies,1,1)."|def";
    $ascii = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
    //ascii = false + Notice: iconv(): Detected an illegal character in input string
    

    对于 UTF-8,很明显必须使用 mb_substr(),而不是 substr().

    使用 iconv,可以将 IGNORE 添加到 TRANSLIT 以忽略非法字符。

    $ascii = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $str);
    //$ascii: string(11) ""a"o"u||def"
    

    在字符串中找到这样的非法字符并不容易。通常的调试输出会伪造这些字符或忽略它们。 遇到这样的问题,我使用这个special class,它也可以重现地显示带有非法UTF-8 的字符串。

    debug::writeUni($str);
    //Output:\u{e4}\u{f6}\u{fc}|\x82|def
    

    可以通过复制和粘贴来接管此输出。

    $str2 = "\u{e4}\u{f6}\u{fc}|\x82|def";
    var_dump($str === $str2); //bool(true)
    

    【讨论】:

      猜你喜欢
      • 2014-08-16
      • 2012-02-02
      • 2012-08-08
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 1970-01-01
      • 1970-01-01
      • 2017-05-13
      相关资源
      最近更新 更多