PHP конвертировать внешний относительный путь в абсолютный путь - PullRequest
4 голосов
/ 20 мая 2010

Я пытаюсь выяснить, как преобразовать «внешний относительный путь» в абсолютный: Мне бы очень хотелось, чтобы функция выполняла следующее:

$path = "/search?q=query";
$host = "http://google.com";
$abspath = reltoabs($host, $path);

И иметь $ abspath, равный "http://google.com/search?q=query" Другой пример:

$path = "top.html";
$host = "www.example.com/documentation";
$abspath = reltoabs($host, $path);

И иметь $ abspath, равный "http://www.example.com/documentation/top.html"

Проблема в том, что он не гарантированно находится в этом формате, и он может уже быть абсолютным или указывать на другой хост целиком, и я не совсем уверен, как к этому подойти. Спасибо.

Ответы [ 3 ]

2 голосов
/ 21 мая 2010

Вы должны попробовать функцию PECL http_build_url http://php.net/manual/en/function.http-build-url.php

1 голос
/ 20 мая 2010

Итак, есть три случая:

  1. правильный URL
  2. без протокола
  3. без протокола и без домена

Пример кода (не проверено):

if (preg_match('@^http(?:s)?://@i', $userurl))
    $url = preg_replace('@^http(s)?://@i', 'http$1://', $userurl); //protocol lowercase
//deem to have domain if a dot is found before a /
elseif (preg_match('@^[^/]+\\.[^/]+@', $useurl)
    $url = "http://".$useurl;
else { //no protocol or domain
    $url = "http://default.domain/" . (($useurl[0] != "/") ? "/" : "") . $useurl;
}

$url = filter_var($url, FILTER_VALIDATE_URL);

if ($url === false)
    die("User gave invalid url").
0 голосов
/ 20 мая 2010

Кажется, я решил свою проблему:

function reltoabs($host, $path) {
    $resulting = array();
    $hostparts = parse_url($host);
    $pathparts = parse_url($path);
    if (array_key_exists("host", $pathparts)) return $path; // Absolute
    // Relative
    $opath = "";
    if (array_key_exists("scheme", $hostparts)) $opath .= $hostparts["scheme"] . "://";
    if (array_key_exists("user", $hostparts)) {
        if (array_key_exists("pass", $hostparts)) $opath .= $hostparts["user"] . ":" . $hostparts["pass"] . "@";
        else $opath .= $hostparts["user"] . "@";
    } elseif (array_key_exists("pass", $hostparts)) $opath .= ":" . $hostparts["pass"] . "@";
    if (array_key_exists("host", $hostparts)) $opath .= $hostparts["host"];
    if (!array_key_exists("path", $pathparts) || $pathparts["path"][0] != "/") {
        $dirname = explode("/", $hostparts["path"]);
        $opath .= implode("/", array_slice($dirname, 0, count($dirname) - 1)) . "/" . basename($pathparts["path"]);
    } else $opath .= $pathparts["path"];
    if (array_key_exists("query", $pathparts)) $opath .= "?" . $pathparts["query"];
    if (array_key_exists("fragment", $pathparts)) $opath .= "#" . $pathparts["fragment"];
    return $opath;
}

Что, кажется, работает очень хорошо для моих целей.

...