测试字符串是否在PHP中进行URL编码

时间:2009-10-28 14:50:21

标签: php testing url-encoding

如何测试字符串是否为URL编码?

以下哪种方法更好?

  • 在字符串中搜索将要编码的字符,这些字符不是,如果存在,则表示未编码,或
  • 使用我做过的这样的东西:

function is_urlEncoded($string){
 $test_string = $string;
 while(urldecode($test_string) != $test_string){
  $test_string = urldecode($test_string);
 }
 return (urlencode($test_string) == $string)?True:False; 
}

$t = "Hello World > how are you?";
if(is_urlEncoded($sreq)){
 print "Was Encoded.\n";
}else{
 print "Not Encoded.\n";
 print "Should be ".urlencode($sreq)."\n";
}

上面的代码可以正常工作,但不是在字符串经过双重编码的情况下,如下例所示:

  • $t = "Hello%2BWorld%2B%253E%2Bhow%2Bare%2Byou%253F";
  • $t = "Hello+World%2B%253E%2Bhow%2Bare%2Byou%253F";

13 个答案:

答案 0 :(得分:33)

我有一个技巧:

你可以这样做以防止双重编码。 每次首先解码然后再次编码;

$string = urldecode($string);

然后再做一次

$string = urlencode($string);

以这种方式执行我们可以避免双重编码:)

答案 1 :(得分:11)

这是我刚刚放在一起的东西。

if ( urlencode(urldecode($data)) === $data){
    echo 'string urlencoded';
} else {
    echo 'string is NOT urlencoded';
}

答案 2 :(得分:10)

你永远不会确定字符串是否是URL编码的,或者它是否应该包含序列%2B。相反,它可能取决于字符串的来源,即它是手工制作还是来自某些应用程序。

  

在字符串中搜索要编码的字符是否更好,哪些字符不存在,如果存在则不编码。

我认为这是一种更好的方法,因为它会处理以编程方式完成的事情(假设应用程序不会留下非编码字符)。

这里有一点令人困惑......从技术上讲,%“应该被编码,如果它将出现在最终值中,因为它是一个特殊字符。您可能必须结合使用方法来查找应该编码的字符,以及验证字符串是否成功解码(如果没有找到)。

答案 3 :(得分:5)

我认为没有万无一失的方法可以做到这一点。例如,请考虑以下事项:

$t = "A+B";

这是一个URL编码为“A B”还是需要编码为“A%2BB”?

答案 4 :(得分:3)

好吧,术语“url编码”有点模糊,也许简单的正则表达式检查会做的伎俩

$is_encoded = preg_match('~%[0-9A-F]{2}~i', $string);

答案 5 :(得分:3)

没有可靠的方法来做到这一点,因为有些字符串在编码过程中保持不变,即是否为“abc”编码?没有明确的答案。另外,正如您所遇到的,一些角色有多种编码......但是......

您的decode-check-encode-check方案失败,因为某些字符可能以多种方式编码。但是,稍微修改一下你的函数应该是相当可靠的,只需检查解码是否修改了字符串,如果是,则进行编码。

当然,它不是万无一失的,因为“10 + 20 = 30”将返回true(+转换为空格),但我们实际上只是在做算术。我想这是你计划试图反击的,我很遗憾地说我认为没有一个完美的解决方案。

HTH。

修改:
正如我在自己的评论中提到的那样(这里只是为了清楚起见),一个很好的折衷方案可能是检查你网址中的无效字符(例如空格),如果有一些字符没有编码。如果没有,请尝试解码并查看字符串是否更改。这仍然不能处理上面的算术(这是不可能的),但希望它足够了。

答案 6 :(得分:2)

怎么样:

if (urldecode(trim($url)) == trim($url)) { $url_form = 'decoded'; }
  else { $url_form = 'encoded'; }

无法使用双重编码,但我认为这超出了范围?

答案 7 :(得分:2)

@ user187291代码可以工作,只有在+未编码时才会失败。

我知道这是很老的帖子。但这对我有用。

$is_encoded = preg_match('~%[0-9A-F]{2}~i', $string);
if($is_encoded) {
 $string  = urlencode(urldecode(str_replace(['+','='], ['%2B','%3D'], $string)));
} else {
  $string = urlencode($string);
}

答案 8 :(得分:1)

发送一个变量,当你从网址获取数据时标记解码。

?path=folder/new%20file.txt&decode=1

答案 9 :(得分:0)

我正在使用以下测试来查看字符串是否已经过urlencoded:

if(urlencode($str) != str_replace(['%','+'], ['%25','%2B'], $str))

如果字符串已经被urlencoded,那么将通过双重编码改变的唯一字符是%(它启动所有编码的字符串)和+(替换空格。)更改它们,你应该有原始字符串。< / p>

请告诉我这是否适合您。

答案 10 :(得分:0)

我找到了。
网址为例如:https://example.com/xD?foo=bar&uri=https%3A%2F%2Fexample.com%2FxD
您需要找到$ _GET ['uri']是否已编码:

preg_match("/.*uri=(.*)&?.*/", $_SERVER['REQUEST_URI'], $r);
if (isset($_GET['uri']) && urldecode($r['1']) === $r['1']) {
  // Code Here if url is not encoded
}

答案 11 :(得分:0)

在我的情况下,我想检查是否对完整的URL进行了编码,因此我已经知道URL必须包含字符串https://,而我所做的就是检查字符串是否具有{ {1}}(https://)中,如果没有,我就知道它没有被编码:

https%3A%2F%2F

理论上,只要您知道部分字符串(在此示例中为//make sure $completeUrl is encoded if (strpos($completeUrl, urlencode('https://')) === false) { // not encoded, need to encode it $completeUrl = urlencode($completeUrl); } )将始终存在于您要检查的内容中​​,则该解决方案可以与除完整URL之外的任何其他字符串一起使用。

答案 12 :(得分:-1)

private static boolean isEncodedText(String val,String ... encoding)throws UnsupportedEncodingException     {         String decodingText = URLDecoder.decode(val,TransformFetchConstants.DEFAULT_CHARSET);

    if(encoding != null && encoding.length > 0){
        decodedText = URLDecoder.decode(val, encoding[0]);
    }

    String encodedText =  URLEncoder.encode(decodedText);

    return encodedText.equalsIgnoreCase(val) || !decodedText.equalsIgnoreCase(val);

}