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 />";
?>

测试的url为http://localhost/test/?a=123!@#&b=123结果报错了:

#号后面的参数被屏蔽了

可以看出“#”号后面的参数被屏蔽了,这很正常,因为“#”号后面的数据不会发送到HTTP请求中。

当url为http://localhost/test/?a=123!@+1&b=123输出为:
运行结果

123!@ 1
123
123!@ 1

可以看出“+”号变成了空格。google了一下找到个解决方案,就是发送数据前先urlencode一下,然后后台再解码。基于这个思路我又试了一下,这次的url为:http://localhost/test/?a=123!%40%23%26%2b&b=123,输出为:

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, "http://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;
?>

运行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, "http://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 = data.replace(/\+/g, “%2B”);

特别是第二种方案,编码两次,解码一次,太脑残了。完全就是为了解决问题而解决问题。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是使用C++实现的程序: ```c++ #include <iostream> #include <string> using namespace std; int main() { string str; getline(cin, str); // 输入字符串 int pos = str.find(","); // 查找逗号的位置 if (pos != string::npos) { // 如果找到了逗号 cout << str.substr(0, pos); // 输出逗号之前的内容 } else { cout << str; // 如果没有找到逗号,直接输出整个字符串 } return 0; } ``` 程序首先使用`getline`函数从标准输入读取输入的字符串,然后使用`find`函数查找字符第一个逗号的位置。如果找到了逗号,就使用`substr`函数输出逗号之前的内容;否则,直接输出整个字符串。 ### 回答2: 编写这个程序可以使用Python编程语言,可以使用字符串的split()方法将输入的字符串按照逗号进行分割,然后取第一个分割结果即可得到逗号之前的内容。 具体代码如下: ```python def get_before_comma(string): comma_index = string.index(',') # 获取逗号字符的索引 content_before_comma = string[:comma_index] # 取出逗号之前的内容 return content_before_comma input_str = input("请输入字符串:") result = get_before_comma(input_str) print("逗号之前的内容为:" + result) ``` 以上就是一个简单的程序,用户输入一个字符串后,程序将返回逗号之前的内容。在这个程序假设输入的字符串一定包含有英文逗号,并且没有考虑一些边界情况,如输入的字符串不包含逗号等。在实际编写,可以根据需求进行优化和完善。 ### 回答3: 编写程序求解这个问题可以使用Python语言实现。算法思路如下: 1. 首先获取用户输入的字符串。 2. 利用内置函数`find()`查找字符英文逗号的索引位置,确定逗号的位置。 3. 使用切片操作从字符串的开头开始截取到逗号之前的位置,保存到变量c。 4. 打印输出变量c。 下面是使用Python编写的程序实现: ```python # 获取用户输入的字符串 string = input("请输入字符串: ") # 查找逗号的位置 comma_index = string.find(',') # 判断是否找到逗号 if comma_index != -1: # 截取字符串 c = string[:comma_index] else: c = "" # 输出结果 print("逗号之前的内容为:", c) ``` 以上程序会先要求用户输入一个字符串,然后会查找逗号的位置并截取逗号之前的内容,最后将结果输出。如果输入的字符不存在逗号,则输出为空字符串。 注意:以上代码使用到了内置函数`input()`和`print()`,用于获取用户输入和输出结果。另外,这段代码还兼容了输入字符不存在逗号的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值