2012-11-19 15 views
8

Ci sono molti post sulla conversione relativa ai percorsi assoluti in PHP. Sto cercando un'implementazione specifica al di là di questi post (si spera). Qualcuno potrebbe aiutarmi con questa specifica implementazione?PHP: Trova immagini e collegamenti con relativo percorso in uscita e convertili in percorso assoluto

Ho una variabile PHP contenente HTML diversi, tra cui href s e img s contenenti url relativi. Per lo più (per esempio) /en/discover o /img/icons/facebook.png

voglio elaborare questa variabile PHP in modo tale che i valori dei miei href s e img s saranno convertiti in http://mydomain.com/en/discover e http://mydomain.com/img/icons/facebook.png

Credo che la domanda qui sotto coperture la soluzione per href s. Come possiamo espandere questo per considerare anche img s?

Sarebbe una regex essere in ordine? O visto che abbiamo a che fare con un sacco di output dovremmo usare DOMDocument?

+0

E non sarebbe utilizzando '' in '' abbastanza? In caso contrario, utilizzare una regex è tutto ciò che si potrebbe fare: in pratica è necessario utilizzare la funzione 'preg_replace_all'. – shadyyx

+0

Grazie per la risposta. Un buon suggerimento, ma non credo, dal momento che l'output verrà visualizzato in un documento XML. Il problema è che sono incompetente con regex ... – maartenmachiels

risposta

8

Dopo alcune ricerche ulteriori sono incappato in questo articolo di Gerd Riesselmann su come risolvere l'assenza di una soluzione base href per i feed RSS. Il suo frammento risolve davvero la mia domanda!

http://www.gerd-riesselmann.net/archives/2005/11/rss-doesnt-know-a-base-url

<?php 
function relToAbs($text, $base) 
{ 
    if (empty($base)) 
    return $text; 
    // base url needs trailing/
    if (substr($base, -1, 1) != "/") 
    $base .= "/"; 
    // Replace links 
    $pattern = "/<a([^>]*) " . 
      "href=\"[^http|ftp|https|mailto]([^\"]*)\"/"; 
    $replace = "<a\${1} href=\"" . $base . "\${2}\""; 
    $text = preg_replace($pattern, $replace, $text); 
    // Replace images 
    $pattern = "/<img([^>]*) " . 
      "src=\"[^http|ftp|https]([^\"]*)\"/"; 
    $replace = "<img\${1} src=\"" . $base . "\${2}\""; 
    $text = preg_replace($pattern, $replace, $text); 
    // Done 
    return $text; 
} 
?> 

Grazie Gerd! E grazie shadyyx per indicarmi la direzione di base href!

4

Soluzione eccellente. Tuttavia, vi è un piccolo errore di battitura nel motivo. Come scritto sopra, tronca il primo carattere di href o src. Qui ci sono i modelli che funzionano come previsto:

// Replace links 
$pattern = "/<a([^>]*) " . 
     "href=\"([^http|ftp|https|mailto][^\"]*)\"/"; 

e

// Replace images 
$pattern = "/<img([^>]*) " . 
     "src=\"([^http|ftp|https][^\"]*)\"/"; 

La parentesi della seconda riferimenti sostituzione di apertura vengono spostati. Questo porta il primo carattere di href o src che non corrisponde a http | ftp | https nei riferimenti di sostituzione.

+0

Grazie, lavora meglio! Solo i link che iniziano con # non dovrebbero essere interessati .. L'utilizzo di [^ http | ftp | https | mailto | #] funziona con '# head1', ma dovrebbe sostituire 'mypage.html # head1' con l'url completo. – Barryvdh

2

Ho scoperto che quando l'href src e l'url di base cominciavano a diventare più complessi, la soluzione di risposta accettata non funzionava per me.

ad esempio:

di base url:

http://www.journalofadvertisingresearch.com/ArticleCenter/default.asp?ID=86411&Type=Article

href src:

/ArticleCenter/LeftMenu.asp?Type=Article&FN=&ID=86411&Vol=&No=&Year=&Any=

in modo non corretto tornato:

/ArticleCenter/LeftMenu.asp?Type=Article&FN=&ID=86411&Vol=&No=&Year=&Any=

ho trovato la funzione di sotto del quale restituisce correttamente l'url. Ho ottenuto questo da un commento qui: http://php.net/manual/en/function.realpath.php da Isaac Z. Schlueter.

Questa correttamente tornato:

http://www.journalofadvertisingresearch.com/ArticleCenter/LeftMenu.asp?Type=Article&FN=&ID=86411&Vol=&No=&Year=&Any=

function resolve_href ($base, $href) { 

// href="" ==> current url. 
if (!$href) { 
    return $base; 
} 

// href="http://..." ==> href isn't relative 
$rel_parsed = parse_url($href); 
if (array_key_exists('scheme', $rel_parsed)) { 
    return $href; 
} 

// add an extra character so that, if it ends in a /, we don't lose the last piece. 
$base_parsed = parse_url("$base "); 
// if it's just server.com and no path, then put a/there. 
if (!array_key_exists('path', $base_parsed)) { 
    $base_parsed = parse_url("$base/ "); 
} 

// href="/ ==> throw away current path. 
if ($href{0} === "/") { 
    $path = $href; 
} else { 
    $path = dirname($base_parsed['path']) . "/$href"; 
} 

// bla/./bloo ==> bla/bloo 
$path = preg_replace('~/\./~', '/', $path); 

// resolve /../ 
// loop through all the parts, popping whenever there's a .., pushing otherwise. 
    $parts = array(); 
    foreach ( 
     explode('/', preg_replace('~/+~', '/', $path)) as $part 
    ) if ($part === "..") { 
     array_pop($parts); 
    } elseif ($part!="") { 
     $parts[] = $part; 
    } 

return ( 
    (array_key_exists('scheme', $base_parsed)) ? 
     $base_parsed['scheme'] . '://' . $base_parsed['host'] : "" 
) . "/" . implode("/", $parts); 
} 
+1

Grazie per il tuo contributo! – maartenmachiels

Problemi correlati