Frage

Wie würde man den Root-DNS-Eintrag von $_SERVER['HTTP_HOST'] bekommen?

Input:

example.co.uk
www.example.com
blog.example.com
forum.example.co.uk 

Ausgabe:

example.co.uk
example.com
example.com
example.co.uk

EDIT: Lookup-Liste ist sehr lang

War es hilfreich?

Lösung

Für dieses Projekt: http://drupal.org/project/parallel

Verbrauch:

echo parallel_get_domain("www.robknight.org.uk") . "<br>";
echo parallel_get_domain("www.google.com") . "<br>";
echo parallel_get_domain("www.yahoo.com") . "<br>";

Funktionen:

/**
 * Given host name returns top domain.
 *
 * @param $host
 *   String containing the host name: www.example.com
 *
 * @return string
 *   top domain: example.com
 */
function parallel_get_domain($host) {
  if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' && strnatcmp(phpversion(),'5.3.0') < 0) {
    // This works 1/2 the time... CNAME doesn't work with nslookup
    for ($end_pieces = substr_count($host, '.'); $end_pieces > 0; $end_pieces--) {
      $test_domain = end(explode('.', $host, $end_pieces));
      if (checkdnsrr($test_domain)) {
          $domain = $test_domain;
          break;
      }
    }
    return isset($domain) ? $domain : FALSE;
  }
  else {
    // This always works
    $sections = explode('.', $host);
    array_unshift($sections, '');
    foreach($sections as $key => $value) {
      $parts[$key] = $value;
      $test_domain = implode('.', parallel_array_xor($parts, $sections));
      if (checkdnsrr($test_domain, 'NS') && !checkdnsrr($test_domain, 'CNAME')) {
        $domain = $test_domain;
        break;
      }
    }
    return isset($domain) ? $domain : FALSE;
  }
}

/**
 * Opposite of array_intersect().
 *
 * @param $array_a
 *   First array
 * @param $array_b
 *   Second array
 *
 * @return array
 */
function parallel_array_xor ($array_a, $array_b) {
  $union_array = array_merge($array_a, $array_b);
  $intersect_array = array_intersect($array_a, $array_b);
  return array_diff($union_array, $intersect_array);
}

/**
 * Win compatible version of checkdnsrr.
 *
 * checkdnsrr() support for Windows by HM2K <php [spat] hm2k.org>
 * http://us2.php.net/manual/en/function.checkdnsrr.php#88301
 *
 * @param $host
 *   String containing host name
 * @param $type
 *   String containing the DNS record type
 *
 * @return bool
 */
function parallel_win_checkdnsrr($host, $type='MX') {
  if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') { return FALSE; }
  if (empty($host)) { return FALSE; }
  $types=array('A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY');
  if (!in_array($type, $types)) {
    user_error("checkdnsrr() Type '$type' not supported", E_USER_WARNING);
    return FALSE;
  }
  @exec('nslookup -type=' . $type . ' ' . escapeshellcmd($host), $output);

  foreach($output as $line){
    if (preg_match('/^' . $host . '/', $line)) { return TRUE; }
  }
}

// Define checkdnsrr() if it doesn't exist
if (!function_exists('checkdnsrr')) {
  function checkdnsrr($host, $type='MX') {
    return parallel_win_checkdnsrr($host, $type);
  }
}

Ausgabe - Fenster:

org.uk
google.com
yahoo.com

Ausgabe - Linux:

robknight.org.uk
google.com
yahoo.com

Andere Tipps

Ich denke, das ist ein bisschen schlecht definiert.

Sie können tun, DNS-Lookups für jeden übergeordneten Datensatz versuchen, bis Sie einen finden, der nicht einen A-Eintrag zurückgibt.

/[^\.]+\.[escaped|list|of|domains]$/

ich denke, das sollte funktionieren.

Wie Sie entdeckt haben, verwenden einige Länder nur TLD (Beispiel: .tv, .us), andere unterteilen ihr Land TLD (Beispiel: uk).

Im Idealfall benötigen Sie eine Lookup-Liste (es wird nicht lange dauern) die zugelassene TLDs, und wenn unterteilt, die TLD mit dem einzelnen Untergliederungen (zB „.net“ statt „.uk“) . Das wird Ihnen sagen, welche „Punkte“ (von rechts) zu halten. Dann bewegen Sie ein nach links von der dot (falls gefunden) und hacken alles vor sich her.

Ohne eine Lookup-Liste können Sie die Tatsache ausnutzen, dass die Unterteilungen (.co, etc.) sind nur für Länder (die mit 2-Buchstaben-TLDs) und sind AFAIK nie mehr als 3 Zeichen selbst und sind immer Briefe, so Sie können sich wahrscheinlich sie mit einem RegexMuster erkennen.

Edit: Nevermind, die aktuelle Liste der öffentlichen Suffixe ist viel komplexer. Sie werden zu müssen gehen eine Lookup-Tabelle zu Abbildung verwenden, was das Suffix ist, gehen Sie zum vorherigen Punkt zurück, und Trimmen links. RegEx ist eine schlechte Lösung. Stattdessen speichern Sie die Liste des Suffixe in einem Wörterbuch, dann Test gegen Ihren Domain-Namen zu einem Zeitpunkt, von links aus einem gepunkteten Abschnitt lopping, bis Sie ein Spiel schlagen, dann den Teil wieder hinzufügen Sie gerade abgeschnitten.

Hinweis: wie erwähnt in den Kommentaren, diese Methode nicht wirklich Arbeit in allen Fällen. Der Grund dafür ist, dass einige Top-Level-Domains zu IP-Adressen auflösen zu tun, auch wenn die meisten nicht. Daher ist es nicht möglich zu erkennen, ob ein bestimmte Name der oberste Ebene oder pseudo-Top-Level-Domain-Namen nur durch Überprüfung ist, wenn sie eine IP-Adresse hat. Leider ist dies wahrscheinlich bedeutet, dass die einzige Lösung ist eine Lookup-Liste, da, wie inkonsequent behandelt Top-Level-Domains in der Praxis ist.

Ich wiederhole: verlassen Sie sich nicht auf den Code unten für Sie zu arbeiten. Ich überlasse es hier nur für Bildungszwecke.

Es gibt eine Möglichkeit, dies ohne eine Lookup-Liste zu tun. Die Liste kann unzuverlässig oder unvollständig sein, während diese Methode zur Arbeit gewährleistet ist:

<?php

function get_domain($url) {
    $dots = substr_count($url, '.');
    $domain = '';

    for ($end_pieces = $dots; $end_pieces > 0; $end_pieces--) {
        $test_domain = end(explode('.', $url, $end_pieces));

        if (dns_check_record($test_domain, 'A')) {
            $domain = $test_domain;
            break;
        }
    }

    return $domain;
}

$my_domain = get_domain('www.robknight.org.uk');

echo $my_domain;

?>

In diesem Fall gibt er ‚robknight.org.uk‘. Ebenso wäre es gut für .com, .edu, .com.au, .ly oder was auch immer andere Top-Level-Domain, die Sie Betrieb auf.

Es funktioniert, indem beginnend von rechts und eine DNS-Überprüfung auf dem ersten, was zu tun, dass sieht aus wie könnte es ein entwicklungsfähige Domain-Name sein. In dem obigen Beispiel, beginnt es mit ‚org.uk‘, aber entdeckt, dass dies keine tatsächlichen Domain-Namen, sondern ist ein ccTLD. Es geht dann zu überprüfen 'robknight.org.uk', die is gültig ist, und kehrt das. Wenn der Domain-Name war, zu sagen: ‚www.php.net‘, wäre es durch Überprüfung ‚php.net‘ begonnen hat, die ein gültiger Domain-Name ist, und das sofort ohne Looping zurückgekehrt wäre. Ich sollte auch diesen Namen, wenn keine gültige Domäne hinweisen gefunden wird, wird eine leere Zeichenfolge ( ‚‘) zurückgegeben.

Dieser Code kann für die Verarbeitung eine große Anzahl von Domain-Namen in kurzer Zeit aufgrund der Zeit, die für DNS-Lookups, aber es ist völlig in Ordnung für einzelne Abfragen oder Code nicht geeignet sein, die nicht zeitkritisch ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top