2009-10-28 74 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); 

}