PHP中GET⽅法参数传递空格+逗号等特殊字符处理办法
⾃⼰在项⽬开发中写了个⾃⽤接⼝,⽤GET⽅法传参(⽤户名和密码)。最近收到⽤户反馈:密码为特殊字符时会出错。我⼀开始想是不是php的mysql_real_escape_string函数将特殊字符转义了,但⽤户说⾃⼰密码只有“+”号这个特殊字符,⽽“+”号不属于该函数转义的范围之内。
为了弄明⽩这个问题我就在本地测试了⼀下,果然发现有bug。
测试代码:
index.php
<?php
echo $_GET['a']."<br />";
echo $_GET['b']."<br />";
echo urldecode($_GET['a'])."<br />";
>
#号后⾯的参数被屏蔽了
可以看出“#”号后⾯的参数被屏蔽了,这很正常,因为“#”号后⾯的数据不会发送到HTTP请求中。
123!@ 1
123
123!@ 1
123!&+
123
123!&
这⾥就有问题了,按理说urldecode后输出的才是正确的,⽹上提供的⽅法都是这样写的。但事实却不是这样,应该是GET⽅法获取值之后会⾃动urldecode,⾃⼰再urldecode就画蛇添⾜了(“+”号⽐较特殊,urldecode之后会变成空格)。所以我们使⽤GET⽅法时只需要将参数urlencode⼀次就⾏了,简单处理⼀下就可解决问题,也不会遇到“+”号的bug。
使⽤POST⽅法就不会出现这些问题,因为POST⽅法会对数据进⾏编码,其中就包括urlcode。但也不是完全不会出现这些问题,在使⽤curl模拟POST⽅法时还是会出现这种问题。
测试代码:
index.php
<?php
echo $_POST['a']."<br />";
echo $_POST['b']."<br />";
echo urldecode($_POST['a'])."<br />";
>
curl.php
<?php
$a = "123!+&";
$post_data = "a=$a&b=123"; //POST值
// 1. 初始化
$ch = curl_init();
// 2. 设置选项
curl_setopt($ch, CURLOPT_URL, "localhost/test/index.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// 3. 执⾏并获取HTML⽂档内容
$text = curl_exec($ch);
/
/ 4. 释放curl句柄
curl_close($ch);
curl是什么命令echo $text;
>
运⾏curl.php的结果:
123! @#
123
123! @#
可以很清楚的看见,虽然没有像GET⽅法那样“#”号后⾯的数据都被忽略了。但获得的数据还是不正确,这是因为curl中POST的值也是像GET⽅法⼀样书写(参数字符串)。其实POST的值也可以写成数组的形式,但那是在提交⽂件流的时候使⽤(Content-Type头将会被设置成multipart/form-data),这⾥(提交数据)使⽤数组的话会出错。参照GET⽅法中的解决⽅案,urlencode⼀下参数值就⾏了。curl.php
<?php
$a = "123!+@#&";
$a = urlencode($a); // url编码,处理特殊字符
$post_data = "a=$a&b=123"; //POST值
// 1. 初始化
$ch = curl_init();
// 2. 设置选项
curl_setopt($ch, CURLOPT_URL, "localhost/test/index.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// 3. 执⾏并获取HTML⽂档内容
$text = curl_exec($ch);
// 4. 释放curl句柄
curl_close($ch);
echo $text;
>
输出:
123!+@#&
123
123! @#&
当然,服务端也不⽤urldecode。
有时⽹上的那些解决⽅案并不是都正确,⼏乎都是复制来复制去的,完全没有考究,⾃⼰在实践过程中要注意辨别。
符⼀个流传很⼴的解决⽅案:
1 、改⽤POST⽅法,ok。
2 、在js⾥⽤url = encodeURI(encodeURI(XXX)),后台再解码⼀次ok。
3 、将参数⾥的加号进⾏转换data = place(/\+/g, “%2B”);
特别是第⼆种⽅案,编码两次,解码⼀次,太脑残了。完全就是为了解决问题⽽解决问题。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论