trayectoria - Transformar la ruta relativa en URL absoluta usando PHP
url relativas y absolutas (8)
¿Cómo, usando php, transformar la ruta relativa a la URL absoluta?
¿No fue de hecho la pregunta sobre la conversión de la ruta y no de la url? PHP en realidad tiene una función para esto: realpath() . Lo único que debe tener en cuenta son los enlaces simbólicos.
Ejemplo del manual de PHP:
chdir(''/var/www/'');
echo realpath(''./../../etc/passwd'') . PHP_EOL;
// Prints: /etc/passwd
echo realpath(''/tmp/'') . PHP_EOL;
// Prints: /tmp
Añadido soporte para mantener la consulta actual. Ayuda mucho para? Page = 1 y así sucesivamente ...
function rel2abs($rel, $base)
{
/* return if already absolute URL */
if (parse_url($rel, PHP_URL_SCHEME) != '''')
return ($rel);
/* queries and anchors */
if ($rel[0] == ''#'' || $rel[0] == ''?'')
return ($base . $rel);
/* parse base URL and convert to local variables: $scheme, $host, $path, $query, $port, $user, $pass */
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 = '''';
/* do we have a user in our URL? */
if (isset($user)) {
$abs .= $user;
/* password too? */
if (isset($pass))
$abs .= '':'' . $pass;
$abs .= ''@'';
}
$abs .= $host;
/* did somebody sneak in a port? */
if (isset($port))
$abs .= '':'' . $port;
$abs .= $path . ''/'' . $rel . (isset($query) ? ''?'' . $query : '''');
/* replace ''//'' or ''/./'' or ''/foo/../'' with ''/'' */
$re = [''#(//.?/)#'', ''#/(?!/./.)[^/]+//././#''];
for ($n = 1; $n > 0; $abs = preg_replace($re, ''/'', $abs, -1, $n)) {
}
/* absolute URL is ready! */
return ($scheme . ''://'' . $abs);
}
Actualicé la función para corregir la URL relativa comenzando con ''//'' mejorando la velocidad de ejecución.
function getAbsoluteUrl($relativeUrl, $baseUrl){
// if already absolute URL
if (parse_url($relativeUrl, PHP_URL_SCHEME) !== null){
return $relativeUrl;
}
// queries and anchors
if ($relativeUrl[0] === ''#'' || $relativeUrl[0] === ''?''){
return $baseUrl.$relativeUrl;
}
// parse base URL and convert to: $scheme, $host, $path, $query, $port, $user, $pass
extract(parse_url($baseUrl));
// if base URL contains a path remove non-directory elements from $path
if (isset($path) === true){
$path = preg_replace(''#/[^/]*$#'', '''', $path);
}
else {
$path = '''';
}
// if realtive URL starts with //
if (substr($relativeUrl, 0, 2) === ''//''){
return $scheme.'':''.$relativeUrl;
}
// if realtive URL starts with /
if ($relativeUrl[0] === ''/''){
$path = null;
}
$abs = null;
// if realtive URL contains a user
if (isset($user) === true){
$abs .= $user;
// if realtive URL contains a password
if (isset($pass) === true){
$abs .= '':''.$pass;
}
$abs .= ''@'';
}
$abs .= $host;
// if realtive URL contains a port
if (isset($port) === true){
$abs .= '':''.$port;
}
$abs .= $path.''/''.$relativeUrl.(isset($query) === true ? ''?''.$query : null);
// replace // or /./ or /foo/../ with /
$re = [''#(//.?/)#'', ''#/(?!/./.)[^/]+//././#''];
for ($n = 1; $n > 0; $abs = preg_replace($re, ''/'', $abs, -1, $n)) {
}
// return absolute URL
return $scheme.''://''.$abs;
}
Esta función resolverá las URL relativas a una url de la página actual en $pgurl
sin $pgurl
regulares . Se resuelve con éxito:
/home.php?example
tipos,
Tipos de nextpage.php
same-dir,
../...../.../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()
deben llamarse después de que la URL se convierta en absoluta.
La función de puntos es un poco redundante, pero es legible, rápida, no usa expresiones regulares y resolverá el 99% de las urls típicas (si desea estar 100% seguro, simplemente extienda el bloque del interruptor para admitir más de 6 puntos, aunque Nunca he visto tantos puntos en una URL).
Espero que esto ayude,
Me encanta el código que jordanstephens proporcionó desde el enlace! Yo lo voté. l0oky me inspiró para asegurarme de que la función sea compatible con el puerto, el nombre de usuario y la contraseña URL. Lo necesitaba para mi proyecto.
function rel2abs( $rel, $base )
{
/* return if already absolute URL */
if( parse_url($rel, PHP_URL_SCHEME) != '''' )
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 = '''';
/* do we have a user in our URL? */
if( isset($user) )
{
$abs.= $user;
/* password too? */
if( isset($pass) )
$abs.= '':''.$pass;
$abs.= ''@'';
}
$abs.= $host;
/* did somebody sneak in a port? */
if( isset($port) )
$abs.= '':''.$port;
$abs.=$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 );
}
Si el directorio relativo ya existe, esto hará el trabajo:
function rel2abs($relPath, $baseDir = ''./'')
{
if ('''' == trim($path))
{
return $baseDir;
}
$currentDir = getcwd();
chdir($baseDir);
$path = realpath($path);
chdir($currentDir);
return $path;
}
Utilicé el mismo código de: http://nashruddin.com/PHP_Script_for_Converting_Relative_to_Absolute_URL pero lo modifiqué un poco, así que si la URL base contiene el número de puerto, devuelve la URL relativa con el número de puerto.
function rel2abs($rel, $base)
{
/* return if already absolute URL */
if (parse_url($rel, PHP_URL_SCHEME) != '''') 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 // with port number if exists */
if (parse_url($base, PHP_URL_PORT) != ''''){
$abs = "$host:".parse_url($base, PHP_URL_PORT)."$path/$rel";
}else{
$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;
}
¡Espero que esto ayude a alguien!
function rel2abs($rel, $base)
{
/* return if already absolute URL */
if (parse_url($rel, PHP_URL_SCHEME) != '''') 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;
}