4

I am trying to figure out how to convert an "external relative path" to an absolute one: I'd really like a function that will do the following:

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

And have $abspath equal to "http://google.com/search?q=query" Another example:

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

And have $abspath equal to "http://www.example.com/documentation/top.html"

The problem is that it is not guaranteed to be in that format, and it could already be absolute, or be pointing to a different host entirely, and I'm not quite sure how to approach this. Thanks.

3
  • If you can post all the different forms of paths & hosts you will get, or at least a good variety, it might help with the direction to do this. Also, where are you getting this data? This might be useful: us3.php.net/manual/en/function.parse-url.php Commented May 20, 2010 at 1:47
  • In theory, this content will be user-generated, and could be all over the place: The hosts could be: "google.com", "google.com/prdhp?hl=en&tab=wf" (i.e. it could include a path) and would need to extract the domain from this string. The paths could range from: "example.com/donuts" to "/testing/n.html" and it would need to detect if a domain is in it. Commented May 20, 2010 at 1:50
  • I guess I need to clarify my previous comment, in that there are two pieces of data given to the program: the HOST, which is the site on which the urls were retrieved from, and the PATH, which is a path that may or may not exist on that site, and if it does not specify a domain, then the domain needs to be pulled from the HOST. Commented May 20, 2010 at 2:28

3 Answers 3

2

You should try the PECL function http_build_url http://php.net/manual/en/function.http-build-url.php

Sign up to request clarification or add additional context in comments.

Comments

1

So there are three cases:

  1. proper URL
  2. no protocol
  3. no protocol and no domain

Example code (untested):

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").

1 Comment

Three cases for the path or the host?
0

It appears I have solved my own problem:

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

Which seems to work pretty well, for my purposes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.