PHP URLDecode/UTF8_使用特殊字符编码字符集问题

PHP URLDecode/UTF8_使用特殊字符编码字符集问题,php,utf-8,character-encoding,urlencode,Php,Utf 8,Character Encoding,Urlencode,我正在将一个英镑符号传递给一个PHP页面,该页面已被ASP URL编码为%C2%A3 问题是: urldecode("%C2%A3") // £ ord(urldecode("%C2%A3")) // get the character number - 194 ord("£") // 163 - somethings gone wrong, they should match 这意味着当我进行utf8编码(urldecode(“%C2%A3”)时,我得到了 然而,在进行utf8编码(“编码

我正在将一个英镑符号
传递给一个PHP页面,该页面已被ASP URL编码为
%C2%A3

问题是:

urldecode("%C2%A3") // £
ord(urldecode("%C2%A3")) // get the character number - 194
ord("£") // 163  - somethings gone wrong, they should match
这意味着当我进行utf8编码(urldecode(“%C2%A3”)时,我得到了

然而,在进行utf8编码(“编码”)时,我得到了预期的结果

我怎样才能解决这个问题呢?

如果你尝试的话

var_dump(urldecode("%C2%A3"));
你会看到的

string(2) "£"
因为这是2字节字符,ord()返回第一个字符的值(194=p)

我不认为
ord()
是多字节兼容的。它可能只返回字符串中第一个字符的代码,即。在对字符串调用
ord()
之前,尝试对其进行
utf8\u解码()
,看看是否有帮助

ord(utf8_decode(urldecode("%C2%A3"))); // This returns 163

有关urldecode和UTF-8的一些信息可以在中找到。这似乎是一个已知的问题。

php.net for urlencode()上的说明了这是为什么,并建议使用以下代码进行更正:

<?php
function to_utf8( $string ) {
// From http://w3.org/International/questions/qa-forms-utf-8.html
    if ( preg_match('%^(?:
      [\x09\x0A\x0D\x20-\x7E]            # ASCII
    | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
    | \xE0[\xA0-\xBF][\x80-\xBF]         # excluding overlongs
    | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
    | \xED[\x80-\x9F][\x80-\xBF]         # excluding surrogates
    | \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
    | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
    | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
)*$%xs', $string) ) {
        return $string;
    } else {
        return iconv( 'CP1252', 'UTF-8', $string);
    }
}
?> 


此外,您还应该决定是否希望发送到浏览器的最终html采用utf-8或其他编码,否则代码中将继续包含字符。

为什么ord(“£”)返回163?如果我硬编码“£”的话,我的其余代码可以正常工作,所以我想让PHP将其识别为char 163,因为您自己键入了它。@Arkh这没有多大帮助,因为我试图让PHP将发布的变量“£”识别为char 163。@Igor K-PHP将
£
识别为163(十六进制:A3),这是正确的,但是你得到了194,因为在A3之前是C2,并且
194=C2
。。。查看上面的
字符串(2)
,但您只看到
“£”
,第一个字符不可见,但仍然存在。在ut8中,您将看到
而不是
,这就是区别。谢谢,这将我的问题分类,将utf8_decode()包装在$u POST[“myvar”]周围,并且它的所有功能都如预期的一样好用!这似乎就是问题所在。这在php中既不是问题,也不是bug。注释引用了错误的客户端编码,这可能是因为缺少UTF8元标记/头。如果您试图修复这样一个错误的请求,您将得到意外的结果。数据正在传递给一个需要UTF-8编码的PHP内置类。你认为有什么理由用这个函数代替utf8_decode()?因为%C2%A3不是utf-8-utf-8-pund应该是%20%A4。您从ASP代码中获得的是iso-8859-1字符。此函数检查字符串是否为有效的utf-8,如果不是,则将其转换为utf8。还可以使用utf8_decode()为您提供iso-8859-1字符,而不是utf-8字符。此函数仅对编码进行猜测,如果未找到任何utf8字符,则执行utf8_编码。如果您在源代码处修复了问题,那么您永远不应该需要这样的东西。