乐趣区

php接收GET方法传入的中文参数乱码深究

最近写了个简单的页面,从浏览器中传入中文参数 (test.php?name= 测试),不论怎么设置 utf- 8 的页面中都显示乱码,google 了一把也查到了不少解决办法,但是问题的原因到底是什么呢?没有人深入研究这个问题。出于好奇便要好好查查到底是什么原因导致,也算涨点经验!
首先先来看下简单的测试代码:

<?php   
header("Content-Type:text/html;charset=UTF-8");   
$name = $_GET['name'];   
var_dump($name);   
?>  

测试结果如下:

代码中声明了响应内容的编码为 utf-8,显示的内容确实乱码。在这里请注意 var_dump 出变量的长度只有 4,很显然,两个中文字的长度在 utf- 8 编码下肯定不止 4 个字节,然后我们再看一下 Firefox 的访问这个页面 url

FireFox 会自动将中文 url 编码,所以我们可以看到测试变成了 %B2%E2%CA%D4,很明显,这里一个字是两个字节,是 gb2313、gbk 等中文编码格式,而不是 utf- 8 编码。如果我们把页面的编码切换为 gbk,中文参数就会显示正常,参见下图

接下来我们做另外一个测试,代码如下:

<?php   
header("Content-Type:text/html;charset=UTF-8");   
$name = $_GET['name'];   
var_dump($name);   
?>   
  
<form method="GET">   
<input name="name" />   
<input type="submit" value="输入中文提交" />   
</form>  

测试结果,正常显示:

那么,是什么导致这个问题的发生呢?
答案是浏览器默认编码在作怪,我们都用的是中文系统,浏览器默认的编码自然也会设置为本地化,例如我自己电脑上的 IE 和 FireFox 的默认编码都是 gb 系列的。
浏览器在请求用户输入的 url 时会默认把 url 中的中文以默认的编码格式发送而不是以页面的编码格式发送,这就是为什么页面中带有中文的链接正常而我们手动输入的链接

会乱码的原因。同理,如果我们把浏览器的默认编码调整为 utf-8,那么输入 url 中的中文则会按照 utf- 8 编码。

除了上面的之外,还有以下情况会出现这种情况:

如果 gbk 编码的页面生成的地址链接到 utf- 8 的页面,gbk 页面的中文是按照 gbk 的格式编码传送给下个页面,那么 utf- 8 编码接收后肯定会出现乱码。
IIS 的 url 重写模块,重写后的中文编码也是 gbk,如果你的页面是 utf- 8 编码,那么重写参数将会失效。像这些情况,我们就需要使用 php 内置的转码函数来处理编码问题了:

方案 1:

$name = iconv("gbk","utf-8",$name);  

方案 2:

mb_convert_encoding($name, "utf-8", "gbk");  
退出移动版