PHP将外部相对路径转换为绝对路径

发布于 2024-09-02 08:13:49 字数 653 浏览 6 评论 0原文

我试图弄清楚如何将“外部相对路径”转换为绝对路径: 我真的很想要一个能够执行以下操作的函数:

$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"

问题是它不能保证采用这种格式,并且它可能已经是绝对的,或者完全指向不同的主机,我不太确定如何解决这个问题。 谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

獨角戲 2024-09-09 08:13:50

您应该尝试 PECL 函数 http_build_url
http://php.net/manual/en/function.http-构建 url.php

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

顾北清歌寒 2024-09-09 08:13:50

因此存在三种情况:

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

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").
沧桑㈠ 2024-09-09 08:13:50

看来我已经解决了我自己的问题:

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

对于我的目的来说,这似乎工作得很好。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文