Question

En PHP, je veux comparer deux URL relatives à l'égalité. La capture: URL peuvent différer en pour cent de codage, par exemple,

  • /dir/file+file par rapport à /dir/file%20file
  • /dir/file(file) par rapport à /dir/file%28file%29
  • /dir/file%5bfile par rapport à /dir/file%5Bfile

Selon RFC 3986 , les serveurs doivent traiter ces URIs de manière identique. Mais si j'utilise == pour comparer, je vais finir avec un décalage.

Je suis à la recherche d'une fonction PHP qui sera accepte deux chaînes et retourne TRUE si elles représentent le même URI (dicounting encodée / décodée variantes du même char, chiffres hexadécimaux majuscules / en minuscules en caractères codés, et + contre %20 pour les espaces) et FALSE si elles sont différentes.

Je sais à l'avance que seuls les caractères ASCII sont dans ces unicode strings-- nô.

Était-ce utile?

La solution

function uriMatches($uri1, $uri2)
{
    return urldecode($uri1) == urldecode($uri2);
}

echo uriMatches('/dir/file+file', '/dir/file%20file');      // TRUE
echo uriMatches('/dir/file(file)', '/dir/file%28file%29');  // TRUE
echo uriMatches('/dir/file%5bfile', '/dir/file%5Bfile');    // TRUE

urldecode

Autres conseils

EDIT: S'il vous plaît consulter la réponse de @ webbiedave. Son est beaucoup mieux (je ne savais même pas qu'il y avait une fonction en PHP pour le faire .. apprendre quelque chose de nouveau tous les jours)

Vous devrez analyser les chaînes à la recherche de quelque chose %## correspondant à trouver les occurences de ceux pour cent de codage. Puis, prenant le nombre de ceux-ci, vous devriez être en mesure de le transmettre de sorte que le chr () fonction pour obtenir le caractère de ces codages pour cent. Reconstruire les cordes et vous devriez être en mesure de les faire correspondre.

Je ne sais pas qui est la méthode la plus efficace, mais étant donné les URL ne sont généralement pas aussi longtemps, il ne devrait pas être trop d'un coup de performance.

Je sais que ce problème semble ici être résolu par webbiedave, mais j'avais mes propres problèmes avec elle.

Le premier problème: les caractères codés sont insensibles à la casse. Donc% C3 et% c3 sont tous deux exactement le même caractère, même si elles sont différentes comme URI. Ainsi, les deux URIs pointent vers le même endroit.

Deuxième problème: le filtre 20% (2) et le dossier% 20% 282% 29 sont tous deux des URIs valablement urlencoded, qui pointent vers le même emplacement, bien qu'ils soient différents URIs

.

Troisième problème:. Si je me débarrasser des caractères codés url J'ai deux emplacements ayant le même URI comme% 2Fblubb et bla bla / blubb

Alors qu'est-ce qu'il faut faire alors? Afin de comparer deux URIs, je dois normaliser tous les deux d'une manière que je les séparer tous les composants, urldecode tous les chemins et requête-pièces pour une fois, les rawurlencode et les recoller ensemble et je pourrais les comparer.

Et cela pourrait être la fonction de la normaliser:

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

Maintenant, vous pouvez modifier la fonction de webbiedave à ceci:

function uriMatches($uri1, $uri2) {
    return normalizeURI($uri1) === normalizeURI($uri2);
}

Cela devrait faire. Et oui, il est tout à fait plus compliqué que même si je voulais que ce soit.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top