PHP:如何解析相对URL

Pau*_*jan 26 php url resolveurl relative-path relative-url

我需要一个给定相对URL的函数,并且base返回一个绝对URL.我搜索并发现许多功能以不同的方式.

resolve("../abc.png", "http://example.com/path/thing?foo=bar")
# returns http://example.com/abc.png
Run Code Online (Sandbox Code Playgroud)

有规范的方法吗?

在这个网站上,我看到了python和c#的很好的例子,让我们得到一个PHP解决方案.

Amb*_*ber 8

也许这篇文章有帮助吗?

http:// nashruddin.com/PHP_Script_for_Converting_Relative_to_Absolute_URL

编辑:为方便起见,下面转载代码

<?php
    function rel2abs($rel, $base)
    {
        /* return if already absolute URL */
        if (parse_url($rel, PHP_URL_SCHEME) != '' || substr($rel, 0, 2) == '//') return $rel;

        /* queries and anchors */
        if ($rel[0]=='#' || $rel[0]=='?') return $base.$rel;

        /* parse base URL and convert to local variables:
         $scheme, $host, $path */
        extract(parse_url($base));

        /* remove non-directory element from path */
        $path = preg_replace('#/[^/]*$#', '', $path);

        /* destroy path if relative url points to root */
        if ($rel[0] == '/') $path = '';

        /* dirty absolute URL */
        $abs = "$host$path/$rel";

        /* replace '//' or '/./' or '/foo/../' with '/' */
        $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
        for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}

        /* absolute URL is ready! */
        return $scheme.'://'.$abs;
    }
?>
Run Code Online (Sandbox Code Playgroud)

  • 它的设计忽略了任何用于此目的的RFC规范.我会说它是***猜测绝对URL或相对的URL. (2认同)

小智 5

如果您有pecl-http,则可以使用http://php.net/manual/en/function.http-build-url.php

<?php
$url_parts = parse_url($relative_url);
$absolute = http_build_url($source_url, $url_parts, HTTP_URL_JOIN_PATH);
Run Code Online (Sandbox Code Playgroud)

例如:

<?php
function getAbsoluteURL($source_url, $relative_url)
{
    $url_parts = parse_url($relative_url);
    return http_build_url($source_url, $url_parts, HTTP_URL_JOIN_PATH);
}
echo getAbsoluteURL('http://foo.tw/a/b/c', '../pic.jpg') . "\n";
// http://foo.tw/a/pic.jpg

echo getAbsoluteURL('http://foo.tw/a/b/c/', '../pic.jpg') . "\n";
// http://foo.tw/a/b/pic.jpg

echo getAbsoluteURL('http://foo.tw/a/b/c/', 'http://bar.tw/a.js') . "\n";
// http://bar.tw/a.js

echo getAbsoluteURL('http://foo.tw/a/b/c/', '/robots.txt') . "\n";
// http://foo.tw/robots.txt
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,`http_build_url` 方法是未与 PHP 捆绑的 PECL 扩展的一部分。 (2认同)

Joh*_*olz 5

如果您已经使用GuzzleHttp ,另一种解决方案。

此解决方案基于 的内部方法GuzzleHttp\Client。

use GuzzleHttp\Psr7;

function resolve(string $uri, ?string $base_uri): string
{
    $uri = Psr7\uri_for($uri);

    if (isset($base_uri)) {
        $uri = Psr7\UriResolver::resolve(Psr7\uri_for($base_uri), $uri);
    }

    // optional: set default scheme if missing
    $uri = $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;

    return (string) $uri;
}
Run Code Online (Sandbox Code Playgroud)