【问题标题】:PHP function iconv character encoding from iso-8859-1 to utf-8PHP 函数 iconv 字符编码从 iso-8859-1 到 utf-8
【发布时间】:2011-04-07 09:23:58
【问题描述】:

我正在尝试将字符串从 iso-8859-1 转换为 utf-8。 但是当我找到这两个字符 € 和 • 函数返回 一个正方形的字符,里面有两个数字。

我该如何解决这个问题?

【问题讨论】:

  • 请展示一些代码和示例数据。
  • € 和 • 两个字符都不包含在 ISO 8859-1 中。那你用什么编码呢?

标签: php utf-8 character-encoding iconv


【解决方案1】:

我认为您正在寻找的编码是Windows code page 1252(西欧)。它与 ISO-8859-1(或 8859-15)不同; 0xA0-0xFF 范围内的字符与 8859-1 匹配,但 cp1252 在 0x80-0x9F 范围内添加了一系列额外字符,其中 ISO-8859-1 分配了很少使用的控制代码。

混淆的原因是当您以text/html;charset=iso-8859-1 提供页面时,由于历史原因,浏览器实际上使用 cp1252(因此也会在 cp1252 中提交表单)。

iconv('cp1252', 'utf-8', "\x80 and \x95")
-> "\xe2\x82\xac and \xe2\x80\xa2"

【讨论】:

  • 谢谢你!现在它起作用了。我现在想问你另一个问题。如何检查 text/html 中设置的所有站点;charset=iso-8859-1 是否真的在 cp1252 中? (你在答案中是如何解释的)。
  • 如果您看到 0x80–0x9F 范围内的字节,您几乎可以肯定看到的是 cp1252 而不是 8859-1,因为“C1 控制代码”很少使用(几乎从不,在网)。如果“ISO-8859-1”字符串的来源是基于网络的,那几乎可以肯定它真的是 cp1252,因为这是浏览器使用的。
  • 我试过这样做 -> mb_detect_encoding($string, 'cp1252');然后使用相同的字符串 mb_detect_encoding($string, 'ISO-8859-1');第一个返回我'false',第二个返回我它是一个ISO-8859-1字符串。但事实并非如此。如何进行特定的字符集检查?
  • 您根本无法进行特定的字符集检查。绝对任何字节序列都是有效的 ISO-8859-1 字符串,并且大多数单字节编码也将所有或大部分字节映射到有效字符。只有像 UTF-8 这样的多字节编码,其中有许多无效的字节序列,才能提供排除它们的任何现实机会。所以真的你只能继续概率的平衡,当来自网络的文本将 cp1252 与 ISO-8859-1 进行比较时,概率的平衡总是 cp1252。
【解决方案2】:

始终首先检查您的编码!你永远不应该盲目相信你的编码(即使它来自你自己的网站!):

function convert_cp1252_to_utf8($input, $default = '') {
    if ($input === null || $input == '') {
        return $default;
    }

    // https://en.wikipedia.org/wiki/UTF-8
    // https://en.wikipedia.org/wiki/ISO/IEC_8859-1
    // https://en.wikipedia.org/wiki/Windows-1252
    // http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT
    $encoding = mb_detect_encoding($input, array('Windows-1252', 'ISO-8859-1'), true);
    if ($encoding == 'ISO-8859-1' || $encoding == 'Windows-1252') {
        /*
         * Because ISO-8859-1 and CP1252 are identical except for 0x80 through 0x9F
         * and control characters, always convert from Windows-1252 to UTF-8.
         */
        $input = iconv('Windows-1252', 'UTF-8//IGNORE', $input);
    }
    return $input;
}

【讨论】:

    【解决方案3】:

    iso-8859-1 不包含 € 符号,因此如果您的字符串包含它,则无法使用 iso-8859-1 解释它。请改用 iso-8859-15。

    【讨论】:

    【解决方案4】:

    这 2 个字符在 iso-8859-1 中是非法的(您是说 iso-8859-15 吗?)

    $ php -r 'echo iconv("utf-8","iso-8859-1//TRANSLIT","ter € and • the");'
    ter EUR and o the
    

    【讨论】:

    • ISO-8859-15 没有 • 的代码点。它必须是Windows-1252。
    • 很可能是的,'has to' 的措辞有点强硬(有多个字符集同时包含 € 和 •)。只要人们知道他们的输入字符集,iconv 解决方案就会保持不变。
    • 好点!然后我又回到了我之前的说法,即 ISO-8859-1 没有子弹。
    猜你喜欢
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2011-07-26
    • 2010-12-08
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多