一个人怎么会得到$_SERVER['HTTP_HOST']根DNS条目?

输入:

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

输出 - 视窗:

org.uk
google.com
yahoo.com

输出 - Linux的:

robknight.org.uk
google.com
yahoo.com

其他提示

我认为这是有点不明确。

您可以尝试做DNS查找每个父记录,直到找到一个不返回的记录。

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

我觉得应该工作。

由于你已经发现,有些国家利用TLD只(例如:.TV,页面没有自动跳转),其他细分自己的国家顶级域名(例如:英国)。

在理想情况下,你需要批准的顶级域名的查找表(它不会很长),并且,如果细分,在TLD每个细分(例如“.co.uk”,而不是“.UK”) 。这会告诉你“点”(右一),以保持它。然后一个点移动到它的左边(如果找到)和之前切碎的一切。

如果没有查找列表,你可以利用一个事实,即细分(.CO等),仅用于国家(其中有2个字母的TLD),并且据我所知不会超过3个字符自己,总是字母,所以你也许可以用正则表达式识别它们。

修改没关系,公共后缀的实际列表要复杂得多。你将需要使用一个查找表找出什么后缀,回到先前点,并修剪左侧。正则表达式是一个不幸的解决方案。取而代之的是,后缀的列表存储在一个字典,然后对你的域名测试,在从左侧时间砍掉一个虚线部分,直到你打一场比赛,然后添加您刚刚修剪掉的部分。

注:在评论中指出,这种方法实际上并不适用于所有情况。这样做的原因是,一些顶级域名解析做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”。这将同样出色的工作提供.com,.edu的,.com.au,.ly或任何其他顶级域名你操作上。

它的工作原理,从右侧开始,做对,看起来像它可能是一个可行的域名的第一件事,一个DNS检查。在上面的例子中,它以“org.uk”,但发现这不是一个实际的域名,而是一个国家代码顶级域名。然后,它前进到检查“robknight.org.uk”,其有效的,并返回。如果域名一直是,比如说,“www.php.net”,它会通过检查“php.net”,这是一个有效的域名开始,并会立即返回,如果没有循环。我还应当指出,如果没有有效的域名中找到,一个空字符串(“”)将被返回。

此代码可能不适合于由于采取DNS查找的时间处理在较短的时间空间的大量的域名,但它是为单个查找或代码,不是时间关键完全正常。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top