我知道这里的这个问题似乎是由 webbiedave 解决的,但我有自己的问题。
第一个问题:编码字符不区分大小写。所以 %C3 和 %c3 都是完全相同的字符,尽管它们作为 URI 是不同的。所以两个 URI 都指向同一个位置。
第二个问题:folder%20(2) 和 folder%20%282%29 都是有效的 urlencoded URI,它们指向同一个位置,尽管它们是不同的 URI。
第三个问题:如果我去掉 url 编码的字符,我有两个位置具有相同的 URI,例如 bla%2Fblubb 和 bla/blubb。
那么该怎么办呢?为了比较两个 URI,我需要以将它们拆分为所有组件的方式对它们进行规范化,一次对所有路径和查询部分进行 urldecode,对它们进行 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);
}
应该这样做。是的,它甚至比我想要的要复杂得多。