globe: wie den Referer filtern

Beitrag lesen

n'abend,

Was mir noch fehlt, ist es, das www. zu entfernen, damit nur noch domain.com statt www.domain.com wiedergegeben wird.

Was passiert denn bei dieser Vorgehensweise, wenn du »http://forum.de.selfhtml.org/?t=187619&m=1247573« als Referer bekommst? Richtig, da gibt's gar kein "www.".

Du willst die Base-Domain haben. Und die haben in aller Regel das Schema »basedomain.tld«.

Nehmen wir als Beispiel mal eine ganze reihe URLs, die du als Referer bekommen könntest als Ausgangsbasis für unseren Test:

'' => null, // kann ja leer sein
  'hallo welt' => null // kann gar keine valide URL sein
  'google.de' => null // nur Domain
  'subdomain.google.de' => null // nur Subdomain
  'http://google.de' => 'google.de' // nur Protokoll und Domain
  'http://intranet' => 'intranet' // "eigene" domains innerhalb eines intranets
  'http://www.google.de' => 'google.de' // www-Subdomain
  'http://www.google.de/advanced_search?hl=de' => 'google.de' // www-Subdomain und Pfad und QueryString
  'http://forum.de.selfhtml.org/my' => 'selfhtml.org' // "ungewöhnliche" Subdomain
  'http://google.de/?ein=querystring' => 'google.de' // QueryString
  'http://google.de/?ein=querystring#fragment' => 'google.de' // Fragment
  'https://www.google.de' => 'google.de' // anderes Protokoll

Schema: URL => erwartetes Ergebnis // Erläuterung

Wir wollen für alle obigen Elemente die entsprechende Base-Domain haben. Wir wissen bereits, dass parse_url() eine URL in seine Bestandteile aufbröseln kann, was uns (verdammt komplizierte) RegExe erspart. Vielen Dank. Von parse_url() bekommen wir also die volle Domain herausgefiltert. Wir wissen, dass die Elemente einer Domain durch einen Punkt von einander getrennt werden. DAS ist eigentlich die wichtigste Information. wir können jetzt nämlich die volle Domain anhand der Punkte in Einzelteile auftrennen lassen und uns dann am vorletzten und letzten Element bedienen, um die Base-Domain wieder zusammenzusetzen. Alternativ könnten wir auch den letzten Punkt suchen. Und irgendwie sollten wir auch noch sicherstellen, dass bei Eingabe von Müll kein Müll zurückgegeben wird.

Was haben wir jetzt gemacht? Wir haben unsere Rahmenbedingungen definiert. Wir haben die Ausgangslage definiert und festgehalten welches Ergebnis wir erwarten. Wir haben uns darüberhinaus überlegt wie wir unnötige Subdomains abtrennen können. Willkommen in der Welt des »Ich habe ein Problem, wie kann ich es lösen?«

Nachdem wir noch ein bisschen in der PHP-Doku herumgestöbert haben, könnten wir die folgenden Test basteln:

<?php  
  
$referers = array(  
  '' => null, // kann ja leer sein  
  'hallo welt' => null, // kann gar keine valide URL sein  
  'google.de' => null, // nur Domain  
  'subdomain.google.de' => null, // nur Subdomain  
  'http://google.de' => 'google.de', // nur Protokoll und Domain  
  'http://intranet' => 'intranet', // "eigene" domains innerhalb eines intranets  
  'http://www.google.de' => 'google.de', // www-Subdomain  
  'http://www.google.de/advanced_search?hl=de' => 'google.de', // www-Subdomain und Pfad und QueryString  
  'http://forum.de.selfhtml.org/my' => 'selfhtml.org', // "ungewöhnliche" Subdomain  
  'http://google.de/?ein=querystring' => 'google.de', // QueryString  
  'http://google.de/?ein=querystring#fragment' => 'google.de', // Fragment  
  'https://www.google.de' => 'google.de', // anderes Protokoll  
);  
  
/**  
 * Retrieve base domain from URL  
 * @param string $url URL to parse  
 * @return string|null determined base domain, or null on failure  
 */  
function getBaseDomain( $url )  
{  
  // abort if there's nothing to parse  
  if( empty($url) )  
    return null;  
  
  // retrieve host from URL  
  // FALSE is returned for invalid URLs, since we can identify them, we can surpress the warning thrown in such a case  
  $host = @parse_url( $url, PHP_URL_HOST );  
  
  // abort if URL could not be parsed  
  if( !$host )  
    return null;  
  
  // split host into components  
  $components = explode( '.', $host );  
  $length = count( $components );  
  
  // "intranet" could be a valid domain inside a company's intranet  
  if( $length < 2 )  
    return $host;  
  
  // the last element will be the TLD (top-level domain)  
  // the second last element will be the actual domain name  
  return $components[ $length -2 ] .'.'. $components[ $length -1 ];  
}  
  
// test getBaseDomain() on given URLs  
echo '<table><tr><th>Eingabe</th><th>Ausgabe</th><th>Status</th></tr>';  
foreach( $referers as $url => $expectedResult )  
{  
  $baseDomain = getBaseDomain( $url );  
  
  echo '<tr>',  
    '<td>', htmlspecialchars( $url ), '</td>';  
  
  if( $baseDomain )  
    echo '<td>', htmlspecialchars( $baseDomain ), '</td>';  
  else  
    echo '<td><em>nichts</em></td>';  
  
  echo '<td>', ( $baseDomain === $expectedResult ? 'OK' : 'fehlerhaft' ), '</td>',  
    '</tr>';  
}  
echo '</table>';  
  
?>

Aus diesem Post solltest du folgendes lernen:

* Ein (großes) Problem kann in viele einzelne Problemchen aufgeteilt werden
 * Du musst die Ausgangssituation kennen
 * Du musst wissen was du erreichen möchtest
 * Du musst in Betracht ziehen, dass es Randbedingungen gibt (keine URL, oder eine invalide URL als Ausgang)
 * Du kennst viele Wege nach Rom, entscheide dich für einen.

weiterhin schönen abend...

--
#selfhtml hat ein Forum?
sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|