utf-8下中文传参乱码【80码求解】

yeyuxuan2006 2009-08-30 10:40:39
测试地址:http://www.dazhongcai.com/test/index.php?cs=我爱中国
问题是这样的,

我直接打开http://www.dazhongcai.com/test/index.php?cs=我爱中国,$_GET['cs']是乱码的。
而从<a href="?cs=我爱中国">我爱中国中文链接</a>点击打开,$_GET['cs']却是正常的。

网上说有用iconv,用后结果变成:
我直接打开http://www.dazhongcai.com/test/index.php?cs=我爱中国,$_GET['cs']是正常的。
而从<a href="?cs=我爱中国">我爱中国中文链接</a>点击打开,$_GET['cs']却是乱码的。

utf-8 下这个就没有解决的办法了吗?
...全文
1792 点赞 收藏 37
写回复
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
sagittaquas 2009-09-01
干嘛gb2312呢,gbk吧:)
回复
yeyuxuan2006 2009-09-01
采用判断每个参数的编码类别,是个好方法,能解决问题,但这样的觉得有点别扭。万一参数多了操作就繁杂了。
只有改成gb2312,无奈之举。
回复
foolbirdflyfirst 2009-08-31
[Quote=引用 20 楼 yeyuxuan2006 的回复:]
引用 18 楼 foolbirdflyfirst 的回复:
还有,不要用用记事本另存为utf-8,会默认加个bom头,header函数会出问题,用编辑器,比如editplus,ultraedit.设置下保存文件不加bom头,

这块之前遇到过这样的问题,页面莫名会多出一行。是不是因为这个?
[/Quote]
是的。bom头搞得鬼。
[Quote=引用 19 楼 yeyuxuan2006 的回复:]
"我爱中国"是数据库其中一个分类标签,采用中文的。
页面链接显示是正常的中文参数,因为所有的编码都是一致的utf-8,并且点击相应的链接,中文也可以url传递且正常接收。
现在问题是手工打开包含中文参数的url时(即无父来源页),中文参数就不能获取了。(这种情况在页面gb2312下是没有的)
[/Quote]
这么说实际上你的页面是正常的了。不太清楚"手工打开包含中文参数的url时(即无父来源页),中文参数就不能获取了",手工打开页面是什么意思?程序发送socket连接?
回复
yeyuxuan2006 2009-08-31
[Quote=引用 18 楼 foolbirdflyfirst 的回复:]
还有,不要用用记事本另存为utf-8,会默认加个bom头,header函数会出问题,用编辑器,比如editplus,ultraedit.设置下保存文件不加bom头,
[/Quote]
这块之前遇到过这样的问题,页面莫名会多出一行。是不是因为这个?
回复
yeyuxuan2006 2009-08-31
"我爱中国"是数据库其中一个分类标签,采用中文的。
页面链接显示是正常的中文参数,因为所有的编码都是一致的utf-8,并且点击相应的链接,中文也可以url传递且正常接收。
现在问题是手工打开包含中文参数的url时(即无父来源页),中文参数就不能获取了。(这种情况在页面gb2312下是没有的)
回复
foolbirdflyfirst 2009-08-31
还有,不要用用记事本另存为utf-8,会默认加个bom头,header函数会出问题,用编辑器,比如editplus,ultraedit.设置下保存文件不加bom头,
回复
foolbirdflyfirst 2009-08-31
<?php
header('Content-Type:text/html;charset=GBK');
$k = "我爱中国"
//$k = iconv("GBK","UTF-8","我爱中国");
print_R($_GET);
echo "<a href='?c={$k}'>我爱中国</a>";
?>
依然保持gb2312编码文件,一切正常。

然后把文件存为utf-8的,你再试下以下代码
<?php
header('Content-Type:text/html;charset=gbk');
$k = "我爱中国";
$k = iconv("utf-8","gbk", $k);
print_R($_GET);
echo "<a href='?c={$k}'>我爱中国</a>";
?>
这时候,<a>标签内的是乱码,$_GET到的正常,因为进行了正确的转码。


回复
foolbirdflyfirst 2009-08-31
嗯,那你"我爱中国"是直接写到程序里的吗,还是从另外的地方获取到的?比如说数据库。
还有url中出现中文会自动进行一次转码.所以iconv转$_GET中的gbk数据是有问题的。应该在传参之前转码。

用一个小例子说明问题可能更好理解点。
<?php
header('Content-Type:text/html;charset=utf-8');
$k = iconv("GBK","UTF-8","我爱中国");
print_R($_GET);
echo "<a href='?c={$k}'>我爱中国</a>";
?>

你把以上这段代码存成一个gb2312的文件,然后用浏览器浏览此文件。会发现<a>标签内的"我爱中国"是乱码,就是因为用utf-8去读gbk,然后点击"我爱中国",会发现$_GET到的是正常的。

回复
yeyuxuan2006 2009-08-31
[Quote=引用 14 楼 foolbirdflyfirst 的回复:]
引用 13 楼 yeyuxuan2006 的回复:
引用 12 楼 foolbirdflyfirst 的回复:
我觉lz你的问题是需要区分文件物理编码和页面编码

比如我有个index.php文件,它的编码是gbk,那么index.php内的"我爱中国"这4个字就是以gbk编码存储到你的操作系统的。
好了,这个时候,你指定了页面的编码
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
这个意思就是浏览器发送请求头到index.php,获取返回内容后,浏览器希望用utf-8编码去识别这个"我爱中国".
但是返回内容是按照它实际物理编码获取到的,所以获取到的"我爱中国"(实际为GBK编码).
这时候就发送乱码行为了。用utf-8编码去读gbk编码的东西,岂不是鸡同鸭讲?
要么你把"我爱中国"这个获取到的内容进行转码,从gbk转到utf-8,要么指定浏览器用gbk编码去识别获取到的数据。


大概明白你的意思了,你的意思是说如果要直接转递"我爱中国"在url中是不行的。除非页面是gb2312,或者gbk? ;utf-8 是行不通的?

其实不是说url传递"我爱中国"不行,而是你得知道这时候传递的这个"我爱中国"是什么样的编码,到了具体url里$_GET到的"我爱中国",浏览器又是用什么编码去读的。如果编码不一致,就肯定乱码了。
其实你保证你的index.php文件编码也是utf-8就行了?
urldecode函数有注入漏洞,我现在不敢用了。
[/Quote]

页面文件的格式也是utf-8(用记事本另存为的),页面编码指定的也是utf-8。我现在已经没有办法了。
回复
foolbirdflyfirst 2009-08-31
[Quote=引用 13 楼 yeyuxuan2006 的回复:]
引用 12 楼 foolbirdflyfirst 的回复:
我觉lz你的问题是需要区分文件物理编码和页面编码

比如我有个index.php文件,它的编码是gbk,那么index.php内的"我爱中国"这4个字就是以gbk编码存储到你的操作系统的。
好了,这个时候,你指定了页面的编码
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
这个意思就是浏览器发送请求头到index.php,获取返回内容后,浏览器希望用utf-8编码去识别这个"我爱中国".
但是返回内容是按照它实际物理编码获取到的,所以获取到的"我爱中国"(实际为GBK编码).
这时候就发送乱码行为了。用utf-8编码去读gbk编码的东西,岂不是鸡同鸭讲?
要么你把"我爱中国"这个获取到的内容进行转码,从gbk转到utf-8,要么指定浏览器用gbk编码去识别获取到的数据。


大概明白你的意思了,你的意思是说如果要直接转递"我爱中国"在url中是不行的。除非页面是gb2312,或者gbk? ;utf-8 是行不通的?
[/Quote]
其实不是说url传递"我爱中国"不行,而是你得知道这时候传递的这个"我爱中国"是什么样的编码,到了具体url里$_GET到的"我爱中国",浏览器又是用什么编码去读的。如果编码不一致,就肯定乱码了。
其实你保证你的index.php文件编码也是utf-8就行了?
urldecode函数有注入漏洞,我现在不敢用了。
回复
yeyuxuan2006 2009-08-31
[Quote=引用 12 楼 foolbirdflyfirst 的回复:]
我觉lz你的问题是需要区分文件物理编码和页面编码

比如我有个index.php文件,它的编码是gbk,那么index.php内的"我爱中国"这4个字就是以gbk编码存储到你的操作系统的。
好了,这个时候,你指定了页面的编码
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
这个意思就是浏览器发送请求头到index.php,获取返回内容后,浏览器希望用utf-8编码去识别这个"我爱中国".
但是返回内容是按照它实际物理编码获取到的,所以获取到的"我爱中国"(实际为GBK编码).
这时候就发送乱码行为了。用utf-8编码去读gbk编码的东西,岂不是鸡同鸭讲?
要么你把"我爱中国"这个获取到的内容进行转码,从gbk转到utf-8,要么指定浏览器用gbk编码去识别获取到的数据。

[/Quote]
大概明白你的意思了,你的意思是说如果要直接转递"我爱中国"在url中是不行的。除非页面是gb2312,或者gbk? ;utf-8 是行不通的?
回复
foolbirdflyfirst 2009-08-31
我觉lz你的问题是需要区分文件物理编码和页面编码

比如我有个index.php文件,它的编码是gbk,那么index.php内的"我爱中国"这4个字就是以gbk编码存储到你的操作系统的。
好了,这个时候,你指定了页面的编码
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
这个意思就是浏览器发送请求头到index.php,获取返回内容后,浏览器希望用utf-8编码去识别这个"我爱中国".
但是返回内容是按照它实际物理编码获取到的,所以获取到的"我爱中国"(实际为GBK编码).
这时候就发送乱码行为了。用utf-8编码去读gbk编码的东西,岂不是鸡同鸭讲?
要么你把"我爱中国"这个获取到的内容进行转码,从gbk转到utf-8,要么指定浏览器用gbk编码去识别获取到的数据。
回复
yeyuxuan2006 2009-08-31
[Quote=引用 9 楼 axolo 的回复:]
用好urlencode和urldecode
[/Quote]
我直接打开这个链接,那怎么去进行urlencode?
http://www.dazhongcai.com/test/index.php?cs=我爱中国
回复
lgzxz999 2009-08-31
[Quote=引用 9 楼 axolo 的回复:]
用好urlencode和urldecode
[/Quote]
支持,解决了也没用,传中文不是直接这么传的
回复
axolo 2009-08-31
用好urlencode和urldecode
回复
yeyuxuan2006 2009-08-31
[Quote=引用 6 楼 foolbirdflyfirst 的回复:]
为什么每天都有编码的问题。。。

你搞清楚什么时候这个"我爱中国"是什么样的编码的就行了。
比如你那个链接,明显是GBK编码的,因为urlencode后为8个 %16进制,正好2个字节一组表示一个中文,而中文在utf-8编码下基本都是3个字节的
[/Quote]
这是那个测试页的源码 http://www.dazhongcai.com/test/index.php?cs=我爱中国

echo "直接接收:".$_GET["cs"]."<br />";
echo "Icov转换的:".iconv("GBK","utf-8",$_GET["cs"])."<br/>";


不是这很明白你的解决方法。。。望指点!
回复
llj480028 2009-08-31
楼上高人呀!学习了!
回复
foolbirdflyfirst 2009-08-31
为什么每天都有编码的问题。。。

你搞清楚什么时候这个"我爱中国"是什么样的编码的就行了。
比如你那个链接,明显是GBK编码的,因为urlencode后为8个 %16进制,正好2个字节一组表示一个中文,而中文在utf-8编码下基本都是3个字节的
回复
ms_X0828 2009-08-31
网上说有用iconv,用后结果变成:
我直接打开http://www.dazhongcai.com/test/index.php?cs=我爱中国,$_GET['cs']是正常的。
而从 <a href="?cs=我爱中国">我爱中国中文链接 </a>点击打开,$_GET['cs']却是乱码的。



楼主你不会都对 我爱中国 进行了iconv 吧?
只对http://....用不就对了吗?
在对<a href="..">时不用iconv不就对了吗
回复
foolbirdflyfirst 2009-08-31
判断编码可以,只能根据大概的编码格式,碰到编码之间的交集部分,就很有可能出错,但也不妨试下.
mb_detect_encoding在这种情况下是用不了的.
utf-8中文一般三个字节,使用对应的unicode模版为
1110xxxx 10xxxxxx 10xxxxxx
x为unicode编码,所以中文utf-8第一个字节的首4位必为16进制的e,第一个字节范围就是e0 - ef
尝试下面的代码
<?php
header('Content-Type:text/html;charset=utf-8');
$k = '我爱中国';
if(!preg_match("/[\xe0-\xef][\x80-\xbf]{2}/",$_GET['c'])){
//找不到utf-8编码的文字就默认为GBK,当然你可以参考gbk的编码格式,做更详细的判断
echo iconv("GBK","UTF-8",$_GET['c']);
}
else
echo $_GET['c'];
echo "<a href='?c={$k}'>我爱中国</a>";
?>

存为utf-8无bom头文件,然后做下测试.
回复
发动态
发帖子
基础编程
创建于2007-09-28

2.1w+

社区成员

从PHP安装配置,PHP入门,PHP基础到PHP应用
申请成为版主
社区公告
暂无公告