Domanda

In PHP, voglio mettere a confronto due URL relativi per l'uguaglianza. La cattura: URL potrebbero differire in percentuale di codifica, ad esempio

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

RFC 3986 , i server dovrebbero trattare questi URI in modo identico. Ma se io uso == per confrontare, finirò con una mancata corrispondenza.

Quindi sto cercando una funzione PHP che sarà accetta due stringhe e restituisce TRUE se rappresentano lo stesso URI (dicounting codificato / decodificato varianti dello stesso carattere, maiuscole / minuscole abbassare cifre esadecimali in caratteri codificati, e + vs. %20 per gli spazi), e FALSE se sono differenti.

So in anticipo che solo i caratteri ASCII sono in questi non unicode strings--.

È stato utile?

Soluzione

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

Altri suggerimenti

Modifica Si prega di guardare la risposta di @ webbiedave. La sua è molto meglio (non ero nemmeno a conoscenza che c'era una funzione in PHP per farlo .. imparare qualcosa di nuovo ogni giorno)

Si dovrà analizzare le stringhe di cercare qualcosa corrispondenza %## per trovare le occorrenze di coloro che codifica per cento. Poi prendendo il numero da quelli, si dovrebbe essere in grado di passare in modo che il chr () funzione per ottenere il carattere di queste codifiche per cento. Ricostruire le corde e allora si dovrebbe essere in grado di corrispondere loro.

Non sono sicuro che sia il metodo più efficace, ma gli URL in considerazione di solito non sono così a lungo, non dovrebbe essere troppo di un calo di prestazioni.

So che questo problema qui sembra essere risolto da webbiedave, ma ho avuto i miei problemi con esso.

problema in primo luogo: codificato personaggi sono maiuscole e minuscole. Così% C3 e C3% sono entrambi lo stesso carattere esatto, anche se sono diversi da un URI. Così entrambe le URI puntare nella stessa posizione.

Secondo problema: cartella% 20 (2) e la cartella% 20% 282% 29 sono entrambi URI validamente urlencoded, che indicano la stessa posizione, anche se sono differenti URI

.

Terzo problema:. Se mi libero dei personaggi URL codificato Ho due posizioni aventi lo stesso URI come bla bla% 2Fblubb e / blubb

Quindi, cosa fare allora? Per confrontare due URI, devo normalizzare entrambi in un modo che li ho diviso in tutti i componenti, urldecode tutti i percorsi e query-parti per una volta, li rawurlencode e incollarli insieme e quindi ho potuto confrontarli.

E questo potrebbe essere la funzione di normalizzare esso:

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

funzione Ora è possibile modificare di webbiedave a questo:

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

Questo dovrebbe fare. E sì, è abbastanza più complicata di quanto anche io volevo che fosse.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top