PHP-Fehler #8192: Function get_magic_quotes_gpc() is deprecated;
Datei: /home/floernco/public_html/webscriptingData/inc/prime.php;
Zeile: 61
href und URL zusammensetzen .· PHP, Benutzerfunktion, Bot .· Webscripting .· floern.com

href und URL zusammensetzen

März 2010

Wenn man beispielsweise einen Robot oder Crawler mit PHP bastelt, ist man meistens gezwungen die Hypertext-Referenzen (href-Attribute) der Links auszulesen. Doch kann man so noch nicht auf die nächste Seite zugreifen, den man besitzt ja die vollständige URL nicht.
Seite: http://example.com/sub/page.php
Verweis: <a href="../otherpage.html">Link</a>
Um an diese zu kommen, müssen die URL und die relative Link-Angabe korrekt zusammengesetzt werden. Das klingt zwar einfach, hat allerdings gewisse Tücken.

Folgende Funktion kombiniert die href-Angabe und die gegebene URL korrekt:
<?php
function combineHrefAndUrl($hrefs$url$killAnchor=true){
  if(!
is_array($hrefs)){
    
$hrefs = array($hrefs);
    
$noArray true;
  }
  
// Fehlernder Root-Slash anfügen
  
if(preg_match('#^[a-z]+://[^/]+$#i'$url)) $url .= '/';
  
// ungültige URL
  
if(!preg_match('#^[a-z]+://[^/]+/.*$#i'$url))
    
trigger_error('Invalid URL: '.htmlspecialchars($url), E_USER_WARNING);
  
// Bestandteile der URL
  
$levels = array();
  
$levels['full'] = $url// unveränderte URL "http://host/dir/file?get#anchor"
  
$levels['url'] = preg_replace('#^([^\#]*)\#.*$#''$1'$levels['full']); // ohne Anker "http://host/dir/file?get"
  
$levels['file'] = preg_replace('#^([^\?]*)\?.*$#''$1'$levels['url']); // ohne Parameter "http://host/dir/file"
  
$levels['dir'] = preg_replace('#/[^/]*$#s''/'$levels['file']); // ohne Datei "http://host/dir/"
  
$levels['root'] = preg_replace('#^([a-z]+://[^/]+)/.*$#i''$1'$levels['dir']); // ohne Verzeichnis "http://host"
  
$levels['scheme'] = preg_replace('#^([a-z]+:).*$#i''$1'$levels['root']); // ohne Host "http:"
  // Die Stücke zusammensetzen
  
foreach($hrefs as &$href){
    
$href html_entity_decode($hrefENT_QUOTES'UTF-8');
    if(
preg_match('#^[a-z]+:#i'$href)) /*void*/// href ist vollständige URL "http://example.com/file.htm"
    
elseif(substr($href02)==='//'$href $levels['scheme'].$href// href ohne Protokoll "//example.com/file.htm"
    
elseif($href[0]==='/'$href $levels['root'].$href// href relativ zum Root "/sub/file.htm"
    
elseif($href[0]==='?'$href $levels['file'].$href// href: nur Parameter "?param=val"
    
elseif($href[0]==='#'$href $levels['url'].$href// href: nur Anker "#anchor"
    
elseif(substr($href02)==='./'$href $levels['dir'].substr($href2); // href: gleiches Verzeichnis "./file.htm"
    
else{ // href: höheres oder gleiches Verzeichnis "../file.htm", "file.htm"
      
$levels['tmpdir'] = $levels['dir'];
      while(
substr($href03)==='../'){
        
$href substr($href3);
        if(
substr_count($levels['tmpdir'], '/')>3)
          
$levels['tmpdir'] = preg_replace('#/[^/]*/[^/]*$#''/'$levels['tmpdir']);
      }
      
$href $levels['tmpdir'].$href;
    }
    
// Fehlernder Root-Slash anfügen
    
if(preg_match('#^[a-z]+://[^/]+$#'$href)) $href .= '/';
    
// Host to lowercase
    
$href preg_replace('#://([^/]+)/#e''"://".strtolower("$1")."/"'$href);
    
// Anker abschneiden
    
if($killAnchor)
      
$href preg_replace('#^([^\#]*)\#.*$#''$1'$href);
  }
  
  return isset(
$noArray) ? array_pop($hrefs) : $hrefs;
}
?>
Diese Funktion erlaubt als $href einen einfachen String sowohl als auch ein Array.
Ist die dritte Variable $killAnchor auf true gesetzt (standardmässig), werden eventuell vorhandene Anker bei einer href entfernt.

<?php
// die Seite
$url 'http://example.com/dir/catalog.php?page=3';

// die Verweise
$hrefs = array(
    
'/',                            # http://example.com/
    
'/anywhere.htm',                # http://example.com/anywhere.htm
    
'./',                           # http://example.com/dir/
    
'./like.php',                   # http://example.com/dir/like.php
    
'like.php?sid=d82eb5',          # http://example.com/dir/like.php?sid=d82eb5
    
'../sub/other.htm',             # http://example.com/sub/other.htm
    
'../../../../../sub/other.htm'# http://example.com/sub/other.htm
    
'#bottom',                      # http://example.com/dir/catalog.php?page=3#bottom
    
'?page=4',                      # http://example.com/dir/catalog.php?page=4
    
'http://example.net/there.asp'# http://example.net/there.asp
    
'mailto:service@example.com',   # mailto:service@example.com
);

$results combineHrefAndUrl($hrefs$urlfalse);
// (Ergebnis siehe oben)
?>

Tipp: Manche Websites verwenden ein <base>-Tag. Wenn dem so ist, muss für $url der Wert des <base>-Tag genommen werden, da die Ergebnis-Links sonst womöglich ungültig sind.
 


Andere Einträge