检测URL查询字符串编码

4
在请求URL中,我可以得到查询字符串?dir=Documents%20partag%C3%A9s?dir=Documents%20partag%E9s。我认为第一个是UTF-8编码,第二个是ASCII编码。
真正的字符串是:Documents partagés 因此,我有一个用PHP编写的脚本(使用UTF-8编码),我想做的是检测查询字符串是ASCII编码还是UTF-8编码,如果是ASCII编码,则将其转换为UTF-8编码。
我尝试过使用mb_函数,但是查询字符串总是被检测为ASCII编码,并且URL解码版本被检测为UTF-8编码。
我应该如何实现这一点?请注意,维基百科有一个类似的功能 - 它将自己编码为%E9,并转换为%C3%A9

也许php.net上的这条评论可以帮到你:http://at2.php.net/manual/en/function.mb-check-encoding.php#95289 - thedom
1个回答

6

E9 在十进制中是233。它不是有效的ASCII字节(仅限0-127),但在ISO-8859-1(Latin1)中是é。当使用mb_convert_encoding时,您可以指定多个编码(例如:UTF-8和ISO-8859-1)。

这应该可以解决问题:

mb_convert_encoding($str, 'UTF-8', 'UTF-8,ISO-8859-1');

使用以下脚本:
$str1 = 'Documents%20partag%E9s';
$str2 = 'Documents%20partag%C3%A9s';
var_dump(mb_convert_encoding(urldecode($str1), 'UTF-8', 'UTF-8,ISO-8859-1'));
var_dump(mb_convert_encoding(urldecode($str2), 'UTF-8', 'UTF-8,ISO-8859-1'));

I get:

string(19) "Documents partagés"
string(19) "Documents partagés"

1
urldecode 将把 %E9 解码为值为 0xE9 的 字节,无论这个字节可能代表什么字符。 - Gumbo
1
这也是错误的。一个字节就是一个字节,字符串也只是一系列字节,它们只是数据而不是信息。只有在特定的字符编码下解释这些字节时,它们才不仅是字节,还代表着字符,因此是信息。 urldecode 仅将 %93 转换为值为 0x93 的字节。仅当使用特定的字符编码(如 ISO 8859-1)解释该字节时,该字节才表示该字符集中的一个字符(只要该字节序列有效)。 - Gumbo
US-ASCII字符集仅有128个字符(使用0x00-0x7F编码)。任何其他字节都是无效的。 - Gumbo
@Gumbo: 等等,这是真的。我觉得我突然混淆了所有字符集。那就算了。 - netcoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接