2010-05-20 6 views
4

J'essaie de comprendre comment convertir un « chemin relatif extérieur » à un absolu: Je voudrais vraiment une fonction qui procédez comme suit:PHP convertir chemin relatif externe au chemin absolu

$path = "https://stackoverflow.com/search?q=query"; 
$host = "http://google.com"; 
$abspath = reltoabs($host, $path); 

Et ont $ abspath égal à "http://google.com/search?q=query" Un autre exemple:

$path = "top.html"; 
$host = "www.example.com/documentation"; 
$abspath = reltoabs($host, $path); 

Et ont abspath $ égal à "http://www.example.com/documentation/top.html"

Le problème est qu'il n'est pas garanti d'être dans ce format, et il pourrait déjà être absolu, ou pointer vers un hôte différent entièrement, et je ne suis pas sûr de la façon d'aborder cela. Merci.

+0

Si vous pouvez afficher toutes les différentes formes de chemins et hôtes que vous obtiendrez, ou au moins une bonne variété, il peut aider à la direction de le faire. Aussi, où obtenez-vous ces données? Cela pourrait être utile: http://us3.php.net/manual/fr/function.parse-url.php –

+0

En théorie, ce contenu sera généré par l'utilisateur, et pourrait être partout: Les hôtes peuvent être: "google.com", "http://www.google.com/prdhp?hl=fr&tab=wf" (c'est-à-dire qu'il peut inclure un chemin) et devront extraire le domaine de cette chaîne. Les chemins peuvent aller de: "example.com/donuts" à "/testing/n.html" et il est nécessaire de détecter si un domaine s'y trouve. – skeggse

+0

Je suppose que je dois clarifier mon commentaire précédent, car il y a deux éléments de données donnés au programme: l'HOST, qui est le site sur lequel les URL ont été récupérées, et le PATH, qui est un chemin qui peut peut ne pas exister sur ce site, et s'il ne spécifie pas de domaine, alors le domaine doit être retiré de l'HÔTE. – skeggse

Répondre

1

Donc, il y a trois cas:

  1. URL correcte
  2. aucun protocole
  3. aucun protocole et aucun domaine

Exemple de code (non testé):

if (preg_match('@^http(?:s)?://@i', $userurl)) 
    $url = preg_replace('@^http(s)?://@i', 'http$1://', $userurl); //protocol lowercase 
//deem to have domain if a dot is found before a/
elseif (preg_match('@^[^/]+\\.[^/][email protected]', $useurl) 
    $url = "http://".$useurl; 
else { //no protocol or domain 
    $url = "http://default.domain/" . (($useurl[0] != "/") ? "/" : "") . $useurl; 
} 

$url = filter_var($url, FILTER_VALIDATE_URL); 

if ($url === false) 
    die("User gave invalid url"). 
+0

Trois cas pour le chemin ou l'hôte? – skeggse

0

Il semble que j'ai résolu mon propre problème:

function reltoabs($host, $path) { 
    $resulting = array(); 
    $hostparts = parse_url($host); 
    $pathparts = parse_url($path); 
    if (array_key_exists("host", $pathparts)) return $path; // Absolute 
    // Relative 
    $opath = ""; 
    if (array_key_exists("scheme", $hostparts)) $opath .= $hostparts["scheme"] . "://"; 
    if (array_key_exists("user", $hostparts)) { 
     if (array_key_exists("pass", $hostparts)) $opath .= $hostparts["user"] . ":" . $hostparts["pass"] . "@"; 
     else $opath .= $hostparts["user"] . "@"; 
    } elseif (array_key_exists("pass", $hostparts)) $opath .= ":" . $hostparts["pass"] . "@"; 
    if (array_key_exists("host", $hostparts)) $opath .= $hostparts["host"]; 
    if (!array_key_exists("path", $pathparts) || $pathparts["path"][0] != "/") { 
     $dirname = explode("/", $hostparts["path"]); 
     $opath .= implode("/", array_slice($dirname, 0, count($dirname) - 1)) . "/" . basename($pathparts["path"]); 
    } else $opath .= $pathparts["path"]; 
    if (array_key_exists("query", $pathparts)) $opath .= "?" . $pathparts["query"]; 
    if (array_key_exists("fragment", $pathparts)) $opath .= "#" . $pathparts["fragment"]; 
    return $opath; 
} 

Ce qui semble fonctionner plutôt bien, pour mes besoins.

Questions connexes