我试图检测字符串的字符编码,但我无法得到正确的结果。
例如:
$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') ;
我又得到了错误的结果
PHP中Windows-1252的问题是它几乎永远不会被检测到,因为只要您的文本包含0x80到0x9f以外的任何字符,它就不会被检测到Windows-1252。
这意味着如果你的字符串包含一个普通的ASCII字母,比如" a ",或者甚至是一个空格字符,PHP会说这不是有效的Windows-1252,在你的情况下,会退回到下一个可能的编码,也就是ISO 8859-1。
尽管使用ISO-8859-1和CP-1252编码的字符串具有不同的字节码表示:
<?php
$str = "€ ‚ ƒ „ …" ;
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
代替parameter会得到非常相似的结果。