PHP: So lösen Sie eine relative URL auf

Lesezeit: 7 Minuten

Ich brauche eine Funktion, die bei einer relativen URL und einer Basis eine absolute URL zurückgibt. Ich habe gesucht und viele Funktionen gefunden, die es auf unterschiedliche Weise tun.

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

Gibt es einen kanonischen Weg?

Auf dieser Seite sehe ich großartige Beispiele für Python und c#, lass uns eine PHP-Lösung bekommen.

  • Dieser Code hat den Trick für mich getan: sourceforge.net/projects/absoluteurl

    – Paul Tarjan

    13. August 09 um 7:43 Uhr


  • Hier ist ein Vergleich von einigen der genannten Lösungen plus einer meiner eigenen.

    – pguardiario

    10. Dezember 12 um 13:14 Uhr

  • Duplikate: stackoverflow.com/questions/4444475/… stackoverflow.com/questions/11653677/… stackoverflow.com/questions/19618754/… stackoverflow.com/questions/26423904/…

    – Qdinar

    3. Januar 16 um 16:04 Uhr

  • fast doppelt: stackoverflow.com/questions/14883501/…

    – Qdinar

    3. Januar 16 um 16:14 Uhr


PHP So losen Sie eine relative URL auf
Bernstein

Vielleicht könnte dieser Artikel helfen?

http://nashruddin.com/PHP_Script_for_Converting_Relative_to_Absolute_URL

Edit: reproduzierter Code unten zur Vereinfachung

<?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] == "https://stackoverflow.com/") $path="";

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

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

        /* absolute URL is ready! */
        return $scheme.'://'.$abs;
    }
?>

  • Diese Implementierung funktioniert nicht, wenn die Basis-URL lautet: foobar.com Ohne abschließendes /. Es berücksichtigt auch keine Portnummern in Basis-URLs.

    – Tom Boutell

    2. Juni 11 um 18:30 Uhr

  • Es ist beabsichtigt, alle RFC-Spezifikationen zu ignorieren, die ohnehin dafür verwendet werden. Ich würde sagen, es ist raten die absolute URL oder eine relative.

    – hakre

    16. September 11 um 15:40 Uhr

1643906046 981 PHP So losen Sie eine relative URL auf
Johannes Buchholz

Eine andere Lösung, falls Sie bereits verwenden GuzzleHttp.

Diese Lösung basiert auf einem internen Verfahren von GuzzleHttpClient.

use GuzzleHttpPsr7;

function resolve(string $uri, ?string $base_uri): string
{
    $uri = Psr7uri_for($uri);

    if (isset($base_uri)) {
        $uri = Psr7UriResolver::resolve(Psr7uri_for($base_uri), $uri);
    }

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

    return (string) $uri;
}

  • Dieser Code ist etwas alt, aber meiner Meinung nach die beste Lösung, hier ist die moderne Version ` use GuzzleHttpPsr7UriResolver; Verwenden Sie GuzzleHttpPsr7Utils; function resolve($uri, $base_uri):string { $uri = Utils::uriFor($uri); if (isset($base_uri)) { $uri = UriResolver::resolve(Utils::uriFor($base_uri), $uri); } // optional: setze Standardschema falls nicht vorhanden $uri = $uri->getScheme() === ” && $uri->getHost() !== ” ? $uri->withScheme(‘http’): $uri; Rückgabe (String) $uri; } `

    – Myriakl

    29. Januar 21 um 21:30 Uhr

Wenn Sie pecl-http haben, können Sie verwenden 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);

Ex:

<?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

  • FYI, die http_build_url -Methode ist Teil einer PECL-Erweiterung, die nicht mit PHP gebündelt ist.

    – mp

    18. Oktober 12 um 18:18 Uhr

  • Das funktioniert wie beschrieben, aber Vorsicht bei der Installation der pecl-Erweiterung. Die neu erschienene Version 2.0 verwendet nun Namespaces und bietet diese Funktion nicht direkt an. Also habe ich eine ältere Version installiert und es funktioniert perfekt für mich: pecl install pecl_http-1.7.6

    – KTB

    10. Januar 14 um 09:29 Uhr


andere Tools, die bereits auf der Seite verlinkt sind, die im Kommentar von pguardiario verlinkt ist: http://publicmind.in/blog/urltoabsolute/ , https://github.com/monkeysuffrage/phpuri .

und ich habe ein anderes Tool aus Kommentar in gefunden http://nadeausoftware.com/articles/2008/05/php_tip_how_convert_relative_url_absolute_url :

require_once 'Net/URL2.php';
$base = new Net_URL2('http://example.org/foo.html');
$absolute = (string)$base->resolve('relative.html#bar'); 

1643906047 741 PHP So losen Sie eine relative URL auf
Joyce Babu

Hier ist eine weitere Funktion, die protokollrelative URLs verarbeiten kann

<?php
function getAbsoluteURL($to, $from = null) {
    $arTarget = parse_url($to);
    $arSource = parse_url($from);
    $targetPath = isset($arTarget['path']) ? $arTarget['path'] : '';

    if (isset($arTarget['host'])) {
        if (!isset($arTarget['scheme'])) {
            $proto = isset($arSource['scheme']) ? "{$arSource['scheme']}://" : '//';
        } else {
            $proto = "{$arTarget['scheme']}://";
        }
        $baseUrl = "{$proto}{$arTarget['host']}" . (isset($arTarget['port']) ? ":{$arTarget['port']}" : '');
    } else {
        if (isset($arSource['host'])) {
            $proto = isset($arSource['scheme']) ? "{$arSource['scheme']}://" : '//';
            $baseUrl = "{$proto}{$arSource['host']}" . (isset($arSource['port']) ? ":{$arSource['port']}" : '');
        } else {
            $baseUrl="";
        }
        $arPath = [];

        if ((empty($targetPath) || $targetPath[0] !== "https://stackoverflow.com/") && !empty($arSource['path'])) {
            $arTargetPath = explode("https://stackoverflow.com/", $targetPath);
            if (empty($arSource['path'])) {
                $arPath = [];
            } else {
                $arPath = explode("https://stackoverflow.com/", $arSource['path']);
                array_pop($arPath);
            }
            $len = count($arPath);
            foreach ($arTargetPath as $idx => $component) {
                if ($component === '..') {
                    if ($len > 1) {
                        $len--;
                        array_pop($arPath);
                    }
                } elseif ($component !== '.') {
                    $len++;
                    array_push($arPath, $component);
                }
            }
            $targetPath = implode("https://stackoverflow.com/", $arPath);
        }
    }

    return $baseUrl . $targetPath;
}

// SAMPLES
// Absolute path => https://www.google.com/doubleclick/
echo getAbsoluteURL('/doubleclick/', 'https://www.google.com/doubleclick/insights/') . "n";
// Relative path 1 => https://www.google.com/doubleclick/studio
echo getAbsoluteURL('../studio', 'https://www.google.com/doubleclick/insights/') . "n";
// Relative path 2 => https://www.google.com/doubleclick/insights/case-studies.html
echo getAbsoluteURL('./case-studies.html', 'https://www.google.com/doubleclick/insights/') . "n";
// Relative path 3 => https://www.google.com/doubleclick/insights/case-studies.html
echo getAbsoluteURL('case-studies.html', 'https://www.google.com/doubleclick/insights/') . "n";
// Protocol relative url => https://www.google.com/doubleclick/
echo getAbsoluteURL('//www.google.com/doubleclick/', 'https://www.google.com/doubleclick/insights/') . "n";
// Empty path => https://www.google.com/doubleclick/insights/
echo getAbsoluteURL('', 'https://www.google.com/doubleclick/insights/') . "n";
// Different url => http://www.yahoo.com/
echo getAbsoluteURL('http://www.yahoo.com/', 'https://www.google.com') . "n";

1643906047 996 PHP So losen Sie eine relative URL auf
Markus Tomlin

function absoluteUri($Path, $URI)
{   # Requires PHP4 or better.
    $URL = parse_url($URI);
    $Str = "{$URL['scheme']}://";

    if (isset($URL['user']) || isset($URL['pass']))
        $Str .= "{$URL['user']}:{$URL['pass']}@";

    $Str .= $URL['host'];

    if (isset($URL['port']))
        $Str .= ":{$URL['port']}";

    $Str .= realpath($URL['path'] . $Path); # This part might have an issue on windows boxes.

    if (isset($URL['query']))
        $Str .= "?{$URL['query']}";

    if (isset($URL['fragment']))
        $Str .= "#{$URL['fragment']}";

    return $Str;
}

absoluteUri("../abc.png", "http://example.com/path/thing?foo=bar");
# Should return "http://example.com/abc.png?foo=bar" on Linux boxes.

PHP So losen Sie eine relative URL auf
Aaron Gillion

Mir ist aufgefallen, dass die positive Antwort oben RegEx verwendet, was beim Umgang mit URLs gefährlich sein kann.

Diese Funktion löst relative URLs zu a auf gegeben aktuelle Seiten-URL in $pgurl ohne Regex. Es löst erfolgreich:

/home.php?example Typen,

gleich dir nextpage.php Typen,

../...../.../parentdir Typen,

voll http://example.net URLs,

und Kurzschrift //example.net URLs

//Current base URL (you can dynamically retrieve from $_SERVER)
$pgurl="http://example.com/scripts/php/absurl.php";

function absurl($url) {
 global $pgurl;
 if(strpos($url,'://')) return $url; //already absolute
 if(substr($url,0,2)=='//') return 'http:'.$url; //shorthand scheme
 if($url[0]=="https://stackoverflow.com/") return parse_url($pgurl,PHP_URL_SCHEME).'://'.parse_url($pgurl,PHP_URL_HOST).$url; //just add domain
 if(strpos($pgurl,"https://stackoverflow.com/",9)===false) $pgurl .= "https://stackoverflow.com/"; //add slash to domain if needed
 return substr($pgurl,0,strrpos($pgurl,"https://stackoverflow.com/")+1).$url; //for relative links, gets current directory and appends new filename
}

function nodots($path) { //Resolve dot dot slashes, no regex!
 $arr1 = explode("https://stackoverflow.com/",$path);
 $arr2 = array();
 foreach($arr1 as $seg) {
  switch($seg) {
   case '.':
    break;
   case '..':
    array_pop($arr2);
    break;
   case '...':
    array_pop($arr2); array_pop($arr2);
    break;
   case '....':
    array_pop($arr2); array_pop($arr2); array_pop($arr2);
    break;
   case '.....':
    array_pop($arr2); array_pop($arr2); array_pop($arr2); array_pop($arr2);
    break;
   default:
    $arr2[] = $seg;
  }
 }
 return implode("https://stackoverflow.com/",$arr2);
}

Anwendungsbeispiel:

echo nodots(absurl('../index.html'));

nodots() muss angerufen werden nach die URL wird in absolut umgewandelt.

Die Punktfunktion ist etwas redundant, aber lesbar, schnell, verwendet keine regulären Ausdrücke und löst 99 % der typischen URLs auf (wenn Sie 100 % sicher sein möchten, erweitern Sie einfach den Schalterblock, um 6+ Punkte zu unterstützen Ich habe noch nie so viele Punkte in einer URL gesehen).

Hoffe das hilft,

.

757550cookie-checkPHP: So lösen Sie eine relative URL auf

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy