PHP: сравнение УРИ, которые отличаются в кодировке процентов

StackOverflow https://stackoverflow.com/questions/3894537

Вопрос

В PHP я хочу сравнить два относительных URL для равенства. Улова: URL могут отличаться в процентах, например,

  • /dir/file+file против. /dir/file%20file
  • /dir/file(file) против. /dir/file%28file%29
  • /dir/file%5bfile против. /dir/file%5Bfile

В соответствии с RFC 3986, Серверы должны лечить эти УРИД. Но если я буду использовать == Для сравнения я в конечном итоге с несоответствием.

Итак, я ищу функцию PHP, которая принимает две строки и возврат TRUE Если они представляют одинаковый URI (кодированные/декодированные варианты DICOUNT + против. %20 для пробелов), и FALSE Если они отличаются.

Я заранее знаю, что в этих строках есть только ascii chars- нет Unicode.

Это было полезно?

Решение

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

урлдокад

Другие советы

РЕДАКТИРОВАТЬ: Пожалуйста, посмотрите на ответ @ WebBiedave. Его намного лучше (я даже не осознавал, что в PHP была функция, чтобы сделать это .. Узнайте что-то новое повседневное)

Вам придется разобрать строки, чтобы искать что-то соответствие %## найти происшествия этих процентов кодирования. Затем принимать номер от тех, вы должны быть в состоянии пройти это так chr () функция, чтобы получить характер этих процентов кодировщиков. Восстановить строки, а затем вы сможете их соответствовать.

Не уверен, что это самый эффективный метод, но, учитывая, что URL -адреса обычно не так долго, это не должно быть слишком большим успехом.

Я знаю, что эта проблема, кажется, решается Webbiedave, но у меня были свои проблемы с ней.

Первая проблема: закодированные символы нечувствительны к регистру. Поэтому% C3 и% C3 являются одними же характером, хотя они отличаются как URI. Таким образом, оба УРИС указывают на одно и то же место.

Вторая проблема: папка%20 (2) и папка%20%282%29 являются обоснованно Urlencodic Uris, которые указывают на одно и то же место, хотя это разные URI.

Третья проблема: если я избавляюсь от кодируемых URL символов, у меня есть два места, имеющие одинаковый URI, как BLA%2FBlubb и Bla/Blubb.

Так что же делать тогда? Чтобы сравнить два URI, мне нужно нормализовать их обоих таким образом, чтобы я разделил их во всех компонентах, на один раз соблюдает все пути и запросы на один раз, 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);
}

Это должно сделать. И да, это довольно сложнее, чем даже я хотел.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top