Frage

In PHP, möchte ich zwei relative URLs für Gleichheit vergleichen. Der Haken: URLs in Prozent-Codierung unterscheiden kann, z.B.

  • /dir/file+file gegen /dir/file%20file
  • /dir/file(file) gegen /dir/file%28file%29
  • /dir/file%5bfile gegen /dir/file%5Bfile

Nach RFC 3986 , sollten Server diese URIs gleich behandeln. Aber wenn ich == verwenden, um vergleichen zu können, werde ich mit einem Mismatch am Ende.

Also ich für eine PHP-Funktion bin auf der Suche, die werden akzeptiert zwei Strings und gibt TRUE wenn sie die gleiche URI (dicounting codierten / decodierten Varianten des gleichen Zeichen, Groß- / Kleinbuchstaben hexadezimale Ziffern in kodierte Zeichen darstellen, und + vs. %20 für Räume) und FALSE wenn sie anders sind.

Ich weiß im Voraus, dass nur ASCII-Zeichen in dieser strings-- keine Unicode sind.

War es hilfreich?

Lösung

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

Andere Tipps

EDIT: Bitte Blick auf @ webbiedave Antwort. Sein ist viel besser (ich nicht einmal bewusst war, dass es eine Funktion in PHP war, das zu tun .. jeden Tag etwas Neues lernen)

Sie werden die Saiten zu suchen etwas passende %## analysieren müssen, um die Vorkommen von jenen Prozent Codierung zu finden. Dann ist die Anzahl von denen nehmen, sollten Sie in der Lage sein, es zu passieren, so dass die chr () Funktion den Charakter jener Prozent Codierungen zu erhalten. Erstellen Sie die Saiten und dann sollten Sie in der Lage sein, sie entsprechen.

Nicht sicher, das ist die effizienteste Methode, aber wenn man bedenkt URLs ist in der Regel nicht so lange, es nicht zu viel von einem Performance-Hit werden soll.

Ich weiß, das Problem hier scheint durch webbiedave gelöst zu werden, aber ich hatte meine eigenen Probleme mit sich.

Erstes Problem: Codierte Zeichen Groß- und Kleinschreibung. So% C3% c3 und sind beide genau die gleiche Charakter, obwohl sie als URI unterschiedlich sind. Also beide URIs verweisen auf die gleiche Stelle.

Zweites Problem: Ordner% 20 (2) und Ordner% 20% 282% 29 sind beide gültig Urlencoded URIs, die auf der gleichen Stelle, obwohl sie unterschiedliche URIs sind

.

Drittes Problem. Wenn ich von den URL-codierten Zeichen loszuwerden Ich habe zwei Stellen die gleiche URI mit wie bla% 2Fblubb und bla / blubb

Also, was dann zu tun? Um zwei URIs zu vergleichen, ich brauche sie beide in einer Art und Weise zu normalisieren, dass ich sie in allen Komponenten aufgeteilt, urldecode alle Pfade und Abfrage-Teile für einmal, rawurlencode sie und kleben sie wieder zusammen und dann konnte ich sie vergleichen.

Und das könnte die Funktion sein, es zu normalisieren:

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

Jetzt können Sie webbiedave die Funktion dieses ändern:

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

sollte das tun. Und ja, es ist ziemlich komplizierter als auch wollte ich es sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top