ここでのこの問題は webbiedave によって解決されているようですが、私自身の問題がありました。
最初の問題: エンコードされた文字は大文字と小文字を区別しません。したがって、%C3 と %c3 はまったく同じ文字ですが、URI としては異なります。したがって、両方の URI が同じ場所を指しています。
2 番目の問題: folder%20(2) と folder%20%282%29 は両方とも有効に urlencode された URI であり、URI は異なりますが、同じ場所を指しています。
3 番目の問題: URL エンコードされた文字を取り除くと、bla%2Fblubb と bla/blubb のような同じ URI を持つ 2 つの場所ができてしまいます。
それで何をすべきか?2 つの URI を比較するには、それらをすべてのコンポーネントに分割し、すべてのパスとクエリ部分を一度に URL デコードし、rawurlencode してそれらを再び結合し、比較できるように両方を正規化する必要があります。
そして、これはそれを正規化する関数である可能性があります:
function normalizeURI($uri) {
$components = parse_url($uri);
$normalized = "";
if ($components['scheme']) {
$normalized .= $components['scheme'] . ":";
}
if ($components['host']) {
$normalized .= "//";
if ($components['user']) { //this should never happen in URIs, but still probably it's anything can happen thursday
$normalized .= rawurlencode(urldecode($components['user']));
if ($components['pass']) {
$normalized .= ":".rawurlencode(urldecode($components['pass']));
}
$normalized .= "@";
}
$normalized .= $components['host'];
if ($components['port']) {
$normalized .= ":".$components['port'];
}
}
if ($components['path']) {
if ($normalized) {
$normalized .= "/";
}
$path = explode("/", $components['path']);
$path = array_map("urldecode", $path);
$path = array_map("rawurlencode", $path);
$normalized .= implode("/", $path);
}
if ($components['query']) {
$query = explode("&", $components['query']);
foreach ($query as $i => $c) {
$c = explode("=", $c);
$c = array_map("urldecode", $c);
$c = array_map("rawurlencode", $c);
$c = implode("=", $c);
$query[$i] = $c;
}
$normalized .= "?".implode("&", $query);
}
return $normalized;
}
これで、webbiedave の機能を次のように変更できます。
function uriMatches($uri1, $uri2) {
return normalizeURI($uri1) === normalizeURI($uri2);
}
それはすべきです。そして、はい、それは私が望んでいたよりもかなり複雑です。