whatwg spec php url relative-path resolveurl relative-url

php - whatwg - html spec



PHP: cómo resolver una URL relativa (6)

Necesito una función que, dada una URL relativa y una base, devuelva una URL absoluta. He buscado y encontré muchas funciones que lo hacen de diferentes maneras.

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

¿Hay alguna manera canónica?

En este sitio veo excelentes ejemplos para python y c #, permite obtener una solución de PHP.


Aquí hay otra función que puede manejar las URL relativas al protocolo

<?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] !== ''/'') && !empty($arSource[''path''])) { $arTargetPath = explode(''/'', $targetPath); if (empty($arSource[''path''])) { $arPath = []; } else { $arPath = explode(''/'', $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(''/'', $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";


Noté que la respuesta arriba expuesta arriba usa RegEx, que puede ser peligroso cuando se trata de URL.

Esta función resolverá las URL relativas a una url de página actual dada en $pgurl sin expresión regular . Se resuelve con éxito:

/home.php?example types,

same-dir nextpage.php tipos,

../...../.../parentdir tipos,

URL completas de http://example.net ,

y taquigrafía //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]==''/'') return parse_url($pgurl,PHP_URL_SCHEME).''://''.parse_url($pgurl,PHP_URL_HOST).$url; //just add domain if(strpos($pgurl,''/'',9)===false) $pgurl .= ''/''; //add slash to domain if needed return substr($pgurl,0,strrpos($pgurl,''/'')+1).$url; //for relative links, gets current directory and appends new filename } function nodots($path) { //Resolve dot dot slashes, no regex! $arr1 = explode(''/'',$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(''/'',$arr2); }

Ejemplo de uso:

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

nodots() debe llamar a nodots() después de que la URL se convierte a absoluta.

La función de puntos es algo redundante, pero es legible, rápida, no usa expresiones regulares, y resolverá el 99% de las direcciones urls típicas (si quiere estar 100% seguro, simplemente extienda el bloque de conmutadores para admitir más de 6 puntos, aunque Nunca he visto tantos puntos en una URL).

Espero que esto ayude,


Si tiene pecl-http, puede usar 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


Tal vez este artículo podría ayudar?

http: // nashruddin.com/PHP_Script_for_Converting_Relative_to_Absolute_URL

Editar: código reproducido a continuación para mayor comodidad

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



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.