文字列が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";
文字列がURLエンコードされているかどうか、またはシーケンス%2B
初期化。代わりに、それはおそらく文字列がどこから来たのか、つまり、手作りであるか、何らかのアプリケーションからのものであるかによって異なります。
エンコードされる文字とエンコードされない文字を文字列で検索し、存在する場合はエンコードされない方が良いですか?.
プログラムで行われたことを処理するため、これはより良いアプローチだと思います(アプリケーションがエンコードされていない文字を残さないと仮定した場合)。
ここで混乱することの1つ...技術的には、%
特殊文字であるため、最終値に存在する場合は「エンコード」する必要があります。エンコードすべき文字を探すためにアプローチを組み合わせる必要があります。また、文字列が見つからない場合に文字列が正常にデコードされることを検証する必要があります。
私は1つのトリックがあります:
これにより、二重エンコードを防ぐことができます。最初にデコードするたびに、再度エンコードします。
$string = urldecode($string);
それからもう一度
$string = urlencode($string);
この方法を実行すると、二重エンコードを回避できます:)
ここに私がまとめたものがあります。
if ( urlencode(urldecode($data)) === $data){
echo 'string urlencoded';
} else {
echo 'string is NOT urlencoded';
}
私はそれを行うための絶対確実な方法はないと思います。たとえば、次のことを考慮してください。
$t = "A+B";
URLは「A B」にエンコードされていますか、それとも「A%2BB」にエンコードする必要がありますか?
どうですか:
if (urldecode(trim($url)) == trim($url)) { $url_form = 'decoded'; }
else { $url_form = 'encoded'; }
ダブルエンコーディングでは動作しませんが、これはとにかく範囲外です?
まあ、「エンコードされたURL」という用語は少し曖昧です。おそらく、単純な正規表現チェックがトリックを行います
$is_encoded = preg_match('~%[0-9A-F]{2}~i', $string);
これを行うための信頼できる方法はありません。エンコードプロセス中に同じままの文字列があります。つまり、「abc」がエンコードされているかどうかです。明確な答えはありません。また、あなたが遭遇したように、いくつかの文字は複数のエンコーディングを持っています...しかし...
いくつかの文字が複数の方法でエンコードされている可能性があるため、decode-check-encode-checkスキームは失敗します。ただし、関数へのわずかな変更はかなり信頼できるはずです。デコードによって文字列が変更されているかどうかを確認してください。変更されている場合は、エンコードされています。
もちろん、「10 + 20 = 30」がtrueを返す(+がスペースに変換される)ので、だまされないわけではありませんが、実際には単に算術演算を行っています。私はこれがあなたがスキームが対抗しようとしているものだと思う、私は完璧な解決策があるとは思わないと言って申し訳ありません。
HTH。
編集:
自分のコメントで述べたように(わかりやすくするためにここで繰り返します)、適切な妥協点は、おそらくURLの無効な文字(スペースなど)をチェックし、ある場合はエンコードされないことです。ない場合は、デコードして、文字列が変更されるかどうかを確認してください。これでも上記の算術演算を処理することはできません(不可能です)が、うまくいけば十分です。
@ 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);
}
すでにURLからデータを取得しているときに、デコードにフラグを立てる変数を送信します。
?path=folder/new%20file.txt&decode=1
見つけた。
URLはFor Forapaple: https://example.com/xD?foo=bar&uri=https%3A%2F%2Fexample.com%2FxD
Found $ _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
}
次のテストを使用して、文字列がurlencodeされているかどうかを確認しています。
if(urlencode($str) != str_replace(['%','+'], ['%25','%2B'], $str))
文字列がすでにurlencodedである場合、ダブルエンコーディングによって変更される文字は、%(すべてのエンコードされた文字列を開始する)と+(スペースを置き換える)のみです。それらを元に戻すと、元の文字列が得られます。
これがうまくいくかどうかを教えてください。