2009-10-28 25 views
16

如何测试字符串是否是URL编码的?测试字符串是否以PHP编码的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";
+1

当您的PHP脚本看到它时,字符串会如何被URL编码?例如,问题是你的脚本是否需要对传入的字符串进行URL解码,或者是脚本需要不对链接href或输入值进行双重编码的问题? – 2011-11-11 23:13:04

+0

如何使用urldecode并将其与原始字符串进行比较。如果它们匹配,它还没有编码。 – thedjaney 2015-09-17 05:42:56

回答

10

如果某个字符串是URL编码的,或者它的序列号应该是%2B,那么您永远都不会知道。相反,它可能取决于字符串来自哪里,即它是手工制作还是来自某些应用程序。

是不是更好地搜索字符串中的字符将被编码,这是不是,如果有任何存在,那么它没有编码。

我认为这是一个更好的方法,因为它会照顾已经编程方式(假设应用程序将不会离开非编码的字符后面)的东西。

有一件事会在这里引起混淆......从技术上讲,%“应该”编码,如果它将出现在最终值中,因为它是一个特殊字符。您可能必须结合您的方法来查找应该被编码的字符,并验证字符串是否成功解码。

+0

“应该有序列”%2B“在其中”,他的解码校验编码检查是试图对此进行解码(解码为空间,编码为%2B,未编码) – falstro 2009-10-28 15:01:52

+0

确实如此,除非意图是将该序列作为最终值传递......你的算术例子是一个更好的例子,它会失败。相反,通过检查“应该”已被编码的字符,应用程序可以更好地了解字符串是否已被编码。 – jheddings 2009-10-28 15:08:18

4

我觉得有没有万无一失的办法做到这一点。例如,请考虑以下内容:

$t = "A+B"; 

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

3

好,术语“URL编码”是一个有点模糊,也许简单的regex检查将这样的伎俩

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

这个错过了“this + string + is + url + encoded” – falstro 2009-10-28 14:58:10

+2

嗯,我以为'+'是url的空间有效编码? – falstro 2009-10-29 14:49:56

3

有没有可靠的方法来做到这一点,因为有它通过保持相同的字符串编码过程,即是否“abc”编码?没有明确的答案。另外,正如你遇到过的,一些字符有多种编码......但是...

由于某些字符可能以多种方式编码,因此解码检查编码检查方案失败。然而,对你的函数稍作修改应该是相当可靠的,只要检查解码是否修改了字符串,如果是,它就被编码了。因为“10 + 20 = 30”将返回true(+被转换为空格),但我们实际上只是在算术。我想这就是你的计划正在试图反击,我很抱歉地说,我不认为有一个完美的解决方案。

HTH。

编辑:
正如我在我自己的评论entioned(只是重申这里的清晰度),一个很好的妥协很可能是来检查您的网址(如空间)无效字符,如果有一些它的没有编码。如果没有,请尝试解码并查看字符串是否更改。这仍然不会处理上面的算法(这是不可能的),但它希望是足够的。

+0

“但是,对函数稍作修改应该相当可靠,只需检查解码是否修改了字符串,如果是,则编码。” 我想这个,但是如果这是字符串“Hello + World你好吗”,那么解码它会产生一个变化,但它不会被完全编码。 – Psytronic 2009-10-28 15:04:22

+0

@Psytronic:非常真实,那是一个不正当的手段。如果您可以找到一种方法来确定它是否是有效的URL,然后解码以检查更改可能是更好的解决方案。你应该能够设计一个正则表达式来寻找像'空格'这样的'坏'字符(如果它无效的话,它不会被编码)。 – falstro 2009-10-28 15:15:09

33

我有一招:

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

$string = urldecode($string); 

然后再做

$string = urlencode($string); 

执行这样,我们才能避免双重编码:)

+1

这是错的!一旦被解码的URL不能以相同的方式编码。有关详细信息,请参阅:http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding 作为路径参数的示例“a + b”是有效。然后如果你解码它,你有相同的字符串(a + b),然后编码结果是“a%2Bb”! – instead 2016-01-05 14:04:52

+1

这会造成麻烦。例如。如果你有一个带有加号的纯文本字符串,如下所示:“TestString Super Mega +”如果你通过urldecode()管道,加号将被删除。 – suther 2017-04-18 08:37:31

1

发送一个变量,它的标志时,你已经从一个URL获取数据的解码。

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

什么:

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

不会与双编码工作,但是这超出了范围反正我想?

+0

尝试与字符串“1 + 1 = 2” – John 2018-01-10 20:14:25

9

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

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

尼斯非常容易的解决方案...简单,干净,快速前进^^。 – suther 2017-04-18 08:40:13

+0

@suther请用各种输入测试它,我不记得,但有时它不能按预期工作。 – AMB 2017-05-26 16:41:59

0

我使用下面的测试,看看是否字符串已url编码:

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

如果字符串已经url编码,将由双编码唯一改变的字符%(这将启动所有编码的字符串)和+(替换空格)。将它们改回来,你应该有原始字符串。

让我知道这是否适合你。

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); 
} 
+0

如果编码与RFC 3986中描述的一样,则正则表达式必须是另一个 – 2017-12-15 16:00:32

-1

私有静态布尔isEncodedText(字符串VAL,字符串...编码)抛出UnsupportedEncodingException { 字符串decodedText = 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); 

}