2010-12-14 12 views
15

¿Cómo, utilizando php, transforma la ruta relativa a la URL absoluta?Transfondo de la ruta relativa a la URL absoluta mediante PHP

+0

dublicates: http://stackoverflow.com/questions/19618754/convert-relative-url-to-absolute-url, http://stackoverflow.com/questions/26423904/converting -relative-url-to-absolute – qdinar

+0

y otro dublicate: http: // stackoverflow.com/questions/11653677/php-relative-urls-to-absolute-urls-conversion-with-event-base-href-html-tag – qdinar

+0

esta pregunta en sí es un duplicado de http://stackoverflow.com/questions/1243418/ php-how-to-resolve-a-relative-url – qdinar

Respuesta

34
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; 
} 
+5

Esto es bastante bueno la mayor parte del tiempo, pero [falla un montón de casos extremos] (https: // github. com/monkeysuffrage/phpuri). – pguardiario

+0

si comienza la url relativa? debería eliminar la parte de consulta de la base antes de dividir las URL relativas y absolutas – qdinar

+0

¿No se supone que '$ rel 'es una cadena con la URL relativa? ¿Por qué estás intentando '$ rel [0]'? Simplemente devuelve un error 'Desvío de cadena sin inicializar: 0'. – HelpingHand

2

¿No era realmente 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 debes tener en cuenta son los enlaces simbólicos.

Ejemplo de manual de PHP:

chdir('/var/www/'); 
echo realpath('./../../etc/passwd') . PHP_EOL; 
// Prints: /etc/passwd 

echo realpath('/tmp/') . PHP_EOL; 
// Prints: /tmp 
+0

¿Podría darnos un ejemplo de su uso? –

+0

@QPaysTaxes ver la actualización. – s3v3n

+2

El resultado de este método es una ruta y no una URL. La pregunta pide URL. – ananda

-1

Si el directorio relativo ya existe esto va a hacer el trabajo:

function rel2abs($relPath, $baseDir = './') 
{ 
if ('' == trim($path)) 
{ 
    return $baseDir; 
    } 
    $currentDir = getcwd(); 
    chdir($baseDir); 
    $path = realpath($path); 
    chdir($currentDir); 
    return $path; 
} 
+2

el parámetro se llama $ relPath pero usa $ path en todo el cuerpo de la función. Corrija uno de esos ... – brew

-2

que utilizan el mismo código de: http://nashruddin.com/PHP_Script_for_Converting_Relative_to_Absolute_URL pero he modificado un poco un bit así que si la URL base contiene el número PORT devuelve la URL relativa con el número de puerto en ella.

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!

5

Me encanta el código que jordanstephens proporciona desde el enlace! Lo voté. l0oky me inspiró para asegurarme de que la función sea compatible con puerto, nombre de usuario y 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); 
} 
+0

pero devolverá la ruta absoluta del sistema de archivos y queremos la url absoluta – siddhesh

+0

Esto debería devolver una URL. ¿Le devuelve una ruta de archivo? –

3

Se agregó compatibilidad para mantener la consulta actual. Ayuda a una gran cantidad de? 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); 
} 
+0

también falla para rel comenzar con "//" – dldnh

-1

Esta función va a resolver la dirección URL de una página en relación con la corriente url dada en $pgurlsin expresiones regulares. Se resuelve con éxito:

/home.php?example tipos,

mismos-dir nextpage.php tipos,

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

completos http://example.net URLs,

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 ser llamado después de la URL se convierte en absoluto.

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

Espero que esto ayude,

+0

... y .... son carpetas normales ... – minmaxavg

Cuestiones relacionadas