2009-10-28 56 views
16

Làm cách nào để kiểm tra xem chuỗi có được mã hóa URL không?Kiểm tra xem chuỗi có được mã hóa bằng URL trong PHP

Phương pháp nào sau đây tốt hơn?

  • Tìm kiếm chuỗi cho các ký tự đó sẽ được mã hóa, mà không phải là, và nếu có tồn tại thì nó không được mã hóa, hoặc
  • Sử dụng một cái gì đó như thế này mà tôi đã thực hiện:

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"; 
} 

Đoạn mã trên hoạt động, nhưng không phải trong trường hợp chuỗi đã được mã hóa gấp đôi, như trong ví dụ sau:

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

Chuỗi sẽ được mã hóa bằng cách nào khi tập lệnh PHP của bạn nhìn thấy? Có phải vấn đề thực sự là tập lệnh của bạn cần phải giải mã URL chuỗi đến hay là vấn đề mà tập lệnh của bạn không cần phải mã hóa kép một liên kết href hoặc giá trị đầu vào chẳng hạn? –

+0

Cách sử dụng urldecode và so sánh nó với chuỗi gốc. Nếu chúng khớp với nó chưa được mã hóa. – thedjaney

Trả lời

10

Bạn sẽ không bao giờ biết chắc chắn nếu chuỗi được mã hóa URL hoặc nếu chuỗi được cho là có chuỗi %2B trong đó. Thay vào đó, nó có thể phụ thuộc vào nơi mà chuỗi đến từ, tức là nếu nó được chế tác thủ công hoặc từ một số ứng dụng.

Tốt hơn nên tìm chuỗi ký tự được mã hóa, ký tự nào không được mã hóa và nếu có thì ký tự không được mã hóa.

Tôi nghĩ đây là một cách tiếp cận tốt hơn, vì nó sẽ chăm sóc những thứ đã được thực hiện theo chương trình (giả sử ứng dụng sẽ không để lại một ký tự không được mã hóa phía sau).

Một điều sẽ gây nhầm lẫn ở đây ... Về mặt kỹ thuật, % "phải được" mã hóa nếu nó sẽ có mặt trong giá trị cuối cùng vì nó là một ký tự đặc biệt. Bạn có thể phải kết hợp các phương pháp của bạn để tìm các ký tự cần mã hóa cũng như xác nhận rằng chuỗi giải mã thành công nếu không tìm thấy.

+0

"phải có chuỗi'% 2B' trong đó ", kiểm tra mã hóa-kiểm tra mã hóa của anh ta là một nỗ lực để chống lại điều này (giải mã vào không gian, mã hóa thành% 2B, không được mã hóa) – falstro

+0

Đúng, trừ khi ý định là chuyển chuỗi đó làm giá trị cuối cùng ... Ví dụ về số học của bạn là một ví dụ tốt hơn nơi mà sẽ thất bại. Thay vào đó, bằng cách kiểm tra các ký tự "nên có" được mã hóa, ứng dụng sẽ nhận được một đầu mối tốt hơn cho dù chuỗi đã được mã hóa hay chưa. – jheddings

4

Tôi nghĩ rằng không có cách nào hoàn hảo để làm điều đó. Ví dụ: hãy xem xét những điều sau:

$t = "A+B"; 

Đó có phải là URL được mã hóa "A B" hay không cần được mã hóa thành "A% 2BB"?

3

tốt, thuật ngữ "url mã hóa" là một chút mơ hồ, có lẽ kiểm tra regex đơn giản sẽ làm các trick

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

điều này bỏ lỡ "chuỗi + này + là + url + được mã hóa" – falstro

+2

hmm, tôi nghĩ '+' là mã hóa không gian hợp lệ trong url? – falstro

3

Không có cách nào đáng tin cậy để làm điều này, vì có dây mà giữ nguyên qua quá trình mã hóa, tức là "abc" được mã hóa hay không? Không có câu trả lời rõ ràng. Ngoài ra, như bạn đã gặp phải, một số ký tự có nhiều mã hóa ... Nhưng ...

Lược đồ kiểm tra mã hóa kiểm tra mã hóa của bạn không thành công do một số ký tự có thể được mã hóa theo nhiều cách. Tuy nhiên, một sửa đổi nhỏ cho chức năng của bạn nên khá đáng tin cậy, chỉ cần kiểm tra xem giải mã có thay đổi chuỗi không, nếu có, nó đã được mã hóa.

Nó sẽ không bị đánh lừa bằng chứng về khóa học, vì "10 + 20 = 30" sẽ trả về true (+ được chuyển đổi thành không gian), nhưng chúng tôi thực sự chỉ làm số học. Tôi cho rằng đây là những gì bạn đang cố gắng để truy cập, tôi xin lỗi để nói rằng tôi không nghĩ rằng có một giải pháp hoàn hảo.

HTH.

Edit:
Như tôi entioned trong bình luận của riêng tôi (chỉ cần nhắc lại ở đây cho rõ ràng), một thỏa hiệp tốt có lẽ là để kiểm tra các ký tự không hợp lệ trong url của bạn (ví dụ như không gian), và nếu có một số đó là không được mã hóa. Nếu không có, hãy thử giải mã và xem chuỗi có thay đổi hay không. Điều này vẫn không xử lý số học trên (điều này là không thể), nhưng hy vọng nó sẽ là đủ.

+0

"Tuy nhiên, một sửa đổi nhỏ cho chức năng của bạn nên khá đáng tin cậy, chỉ cần kiểm tra xem giải mã sửa đổi chuỗi, nếu nó, nó đã được mã hóa." Tôi nghĩ rằng điều này, tuy nhiên nếu đây là chuỗi "Xin chào + Thế giới thế nào là bạn" sau đó giải mã nó sẽ tạo ra một sự thay đổi, nhưng nó sẽ không được mã hóa đầy đủ. – Psytronic

+0

@Psytronic: Rất đúng, đó là một bugger không phải là nó. Nếu bạn có thể tìm cách xác định xem đó có phải là URL hợp lệ không, sau đó giải mã để kiểm tra thay đổi có thể là giải pháp tốt hơn. Bạn sẽ có thể đưa ra một biểu thức chính quy để tìm các ký tự 'xấu' như không gian (nếu nó không hợp lệ, nó không được mã hóa). – falstro

33

tôi có một mẹo:

bạn có thể thực hiện việc này để ngăn mã hóa kép. Mỗi lần giải mã lần đầu tiên sau đó mã hóa lại;

$string = urldecode($string); 

Sau đó làm lại

$string = urlencode($string); 

Performing cách này chúng ta có thể tránh được mã hóa gấp đôi :)

+1

Điều đó là sai! URL đã từng được giải mã, không thể được mã hóa theo cùng một cách. Để biết thêm thông tin, hãy kiểm tra: http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding Ví dụ "a + b" làm thông số đường dẫn có hiệu lực. Sau đó, nếu bạn giải mã nó, bạn có cùng một chuỗi (a + b), và sau đó sau khi mã hóa kết quả là "a% 2Bb"! – instead

+1

Điều này sẽ gây ra rắc rối. Ví dụ. nếu bạn có một chuỗi văn bản thuần túy với một dấu cộng như thế này: "TestString Super Mega +" Dấu cộng sẽ được loại bỏ, nếu bạn ống nó máng urldecode(); – suther

1

gửi một biến cờ giải mã khi bạn đã nhận được dữ liệu từ một url.

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

gì về:

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

sẽ không làm việc với mã hóa gấp đôi nhưng điều này nằm ngoài phạm vi anyway tôi giả sử?

+0

hãy thử với chuỗi "1 + 1 = 2" – John

9

Đây là thứ tôi vừa ghép lại với nhau.

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

Giải pháp khá dễ dàng ... đơn giản, sạch sẽ, nhanh chóng chuyển tiếp^^. – suther

+0

@suther hãy kiểm tra nó với các đầu vào khác nhau, tôi không nhớ nhưng đôi khi nó không hoạt động như mong đợi. – AMB

0

Tôi đang sử dụng thử nghiệm sau để xem nếu chuỗi đã được urlencoded:

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

Nếu một chuỗi đã được urlencoded, các nhân vật duy nhất mà sẽ thay đổi bằng cách mã hóa kép là% (trong đó bắt đầu tất cả các chuỗi ký tự được mã hóa) và + (thay thế dấu cách.) Thay đổi chúng trở lại và bạn nên có chuỗi gốc.

Hãy cho tôi biết nếu điều này phù hợp với bạn.

2

@ user187291 mã hoạt động và chỉ thất bại khi + không được mã hóa.

Tôi biết đây là bài đăng rất cũ. Nhưng điều này làm việc với tôi.

$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

Nếu mã hóa như được mô tả trong RFC 3986, regex phải là mã hóa khác –

-1

private static boolean isEncodedText (String val, String ... mã hóa) ném UnsupportedEncodingException { Chuỗi 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); 

} 
Các vấn đề liên quan