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.
<?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
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; } `
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
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.
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 $pgurlohne 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,
.
7575500cookie-checkPHP: So lösen Sie eine relative URL aufyes
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