2013-04-05 52 views
4

我试图检测字符串的字符编码,但我无法得到正确的结果。
例如:在PHP中检测正确的字符编码?

$str = "€ ‚ ƒ „ …" ; 
$str = mb_convert_encoding($str, 'Windows-1252' ,'HTML-ENTITIES') ; 
// Now $str should be a Windows-1252-encoded string. 
// Let's detect its encoding: 
echo mb_detect_encoding($str,'Windows-1252, ISO-8859-1, UTF-8') ; 

即代码输出ISO-8859-1但它应该是Windows-1252

这是怎么回事?

编辑:
更新的示例,以回应@ raina77ow。

$str = "€‚ƒ„…" ; // no white-spaces 
$str = mb_convert_encoding($str, 'Windows-1252' ,'HTML-ENTITIES') ; 
$str = "Hello $str" ; // let's add some ascii characters 
echo mb_detect_encoding($str,'Windows-1252, ISO-8859-1, UTF-8') ; 

我再次得到错误的结果。

+0

什么是您使用的PHP版本?它在这里显示正确http://codepad.viper-7.com/NfvdWm。顺便说一句,你应该总是首先列出UTF-8,因为它是最受限制的。可能根本不需要ISO-8859-1,因为任何东西都是有效的ISO-8859-1。 – Esailija 2013-04-06 09:25:55

+0

@Esailija,你没有使用问题中任何两个例子的代码。试试这两个例子中的任何一个,你就会得到结果'ISO-8859-1'。 – GetFree 2013-04-07 01:17:10

回答

0

虽然与ISO-8859-1和CP-1252编码字符串有不同的字节码表示:

<?php 
$str = "&euro; &sbquo; &fnof; &bdquo; &hellip;" ; 
foreach (array('Windows-1252', 'ISO-8859-1') as $encoding) 
{ 
    $new = mb_convert_encoding($str, $encoding, 'HTML-ENTITIES'); 
    printf('%15s: %s detected: %10s explicitly: %10s', 
     $encoding, 
     implode('', array_map(function($x) { return dechex(ord($x)); }, str_split($new))), 
     mb_detect_encoding($new), 
     mb_detect_encoding($new, array('ISO-8859-1', 'Windows-1252')) 
    ); 
    echo PHP_EOL; 
} 

结果:

Windows-1252: 802082208320842085 detected:   explicitly: ISO-8859-1 
    ISO-8859-1: 3f203f203f203f203f detected:  ASCII explicitly: ISO-8859-1 

...从我们可以在这里看到它看起来像mb_detect_encoding的第二参数有问题。使用mb_detect_order而不是参数产生非常相似的结果。

+0

示例中的字符在ISO-8859-1中不存在。 – GetFree 2013-04-05 22:04:27

+0

我列表中的第一个匹配编码是'Windows-1252'。 “ISO-8859-1”是列表中的第二位。 – GetFree 2013-04-05 22:23:33

+1

@GetFree php字符串不是字符,而是字节。任何PHP字符串都是有效的“ISO-8859-1”,因为任何字节都是有效的ISO-8859-1。 – Esailija 2013-04-06 09:24:36

1

PHP中Windows-1252的问题在于,它几乎可以检测到从不,因为只要您的文本包含0x80到0x9f以外的任何字符,它就不会被检测为Windows-1252。

这意味着如果你的字符串包含一个普通的ASCII字母,如“A”,甚至空格字符,PHP会说这是无效的Windows-1252,在你的情况下,回退到下一个可能的编码,这是ISO 8859-1。这是一个PHP错误,请参阅https://bugs.php.net/bug.php?id=64667