PHP サーバーからルート DNS エントリを取得します。wwwなどを含まないドメイン名を取得します

StackOverflow https://stackoverflow.com/questions/1375647

  •  21-09-2019
  •  | 
  •  

質問

ルート DNS エントリを取得するにはどうすればよいですか? $_SERVER['HTTP_HOST']?

入力:

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

出力:

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

編集:ルックアップリストは とても長い

役に立ちましたか?

解決

このプロジェクトのために: http://drupal.org/project/parallelする

使用方法:

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>";

機能:

/**
 * 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);
  }
}

出力 - Windowsの場合:

org.uk
google.com
yahoo.com

出力 - Linuxの場合:

robknight.org.uk
google.com
yahoo.com

他のヒント

私はそれが少し不明確だと思います。

あなたはAレコードを返さないものを見つけるまで、各親レコードのDNSルックアップをやってみてください可能性があります。

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

私はそれが動作するはずだと思います。

あなたが発見したように、一部の国は、TLDのみ(例:.TV、.US)を使用し、

、他の人は、TLD(例:英国)自分たちの国を細分化します。

理想的には、あなたは、ルックアップ承認のTLDのリスト(それは長くはありません)、そして、細分化すれば、それぞれの細分化とTLD(例えば、「.co.uk」の代わりに「.ukのを」)が必要です。それは維持する(右から)あなたはどの「ドット」を教えてくれます。そして、1はそのことを左に(もし見つかれば)、それ以前にチョップすべてにドット移動します。

ルックアップリストがなければ、あなたはそう、細分化(.COなど)(2文字のTLDを持っている)と私の知る限りでは決して以上3つの文字で自分自身をし、文字が常にある国のみであるという事実を利用することができますあなたはおそらく正規表現パターンでそれらを認識することができます。

編集のネヴァーマインド、公共のサフィックスの実際のリストははるかに複雑です。あなたは戻って、以前のドット、およびトリム左に行く、接尾語が何であるかを把握するのルックアップテーブルを使用する必要があるとしています。正規表現は、ここでは貧弱なソリューションです。代わりに、あなたは試合を打つまで、あなただけ切り取ら一部をバック追加し、左から一度に1つの点線の部分をオフlopping、自分のドメイン名に対するテスト、その後、辞書にあるサフィックスのリストを格納します。

の注:コメント欄で先の尖ったアウトとして、この方法は、すべてのケースで、実際に仕事をしません。この理由は、いくつかのトップレベルドメインは、ほとんどがいない場合でも、IPアドレスに解決を行うということです。したがって、それは与えられた名前は、それがIPアドレスを持っているかどうかをチェックするだけで、トップレベルまたは擬似トップレベルドメイン名であるかどうかを検出することはできません。残念ながら、唯一の解決策は、与えられたルックアップリストは、トップレベルドメインが実際にどのように一貫性なく治療これはおそらく手段であること。

の私は繰り返し:あなたのために仕事に以下のコードに依存しないでください。私は教育目的のために、ここでそれを残す。

、ルックアップリストなしでこれを行う方法があります。この方法は仕事に保証されているのに対し、リストには、信頼できないか、不完全な可能性があります:

<?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;

?>

この場合には、それが出力されます「robknight.org.uk」。それは、上または任意の他のトップレベルドメインあなたにしているオペレーティングを.ly、.COM、.eduさらに、.com.auのためにも同様に動作します。

これは右から始まり、それのようなルックスは、実行可能なドメイン名であるかもしれないことを最初にDNSチェックを行うことで動作します。上記の例では、それはorg.uk 'で始まるが、発見これは実際のドメイン名ではなく、ccTLDのであること。それは、その<全角>は、「robknight.org.uk」をチェックするために上を移動するのある有効な、戻ります。ドメイン名があった場合、それが有効なドメイン名である「php.net」チェックすることで開始しているだろう、とループせずにその直後に戻っているだろう、「www.php.net」と言います。私はまた、有効なドメイン名が見つからない場合、空の文字列(「」)が返されることを指摘しなければならない。

このコードが原因DNS検索に要する時間までの時間の短いスペースでドメイン名の多数を処理するには不向きかもしれないが、それは時間が重要ではない、単一の検索やコードのために完全に罰金です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top