Nasıl bir gelen kök DNS girdisini alacağı $_SERVER['HTTP_HOST']
?
Girdi:
example.co.uk
www.example.com
blog.example.com
forum.example.co.uk
Çıktı:
example.co.uk
example.com
example.com
example.co.uk
EDIT: Lookup list is very long
Nasıl bir gelen kök DNS girdisini alacağı $_SERVER['HTTP_HOST']
?
Girdi:
example.co.uk
www.example.com
blog.example.com
forum.example.co.uk
Çıktı:
example.co.uk
example.com
example.com
example.co.uk
EDIT: Lookup list is very long
Bu proje için: http://drupal.org/project/parallel
Kullanımı:
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>";
Fonksiyonlar:
/**
* 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);
}
}
Çıktı - Windows:
org.uk
google.com
yahoo.com
Çıktı - Linux:
robknight.org.uk
google.com
yahoo.com
Fark ettik gibi, bazı ülkeler bir TLD sadece (örnek..: Tv, us) kullanmak, başkalarının kendi ülke TLD (örnek: tr) ayırabiliriz.
İdeali, bölünmüş ise, her alt ile TLD (örneğin, yerine ". Uk" nin ". Co.uk"), onaylı TLD'lerin (uzun olmayacak) bir arama listesi gerekir, ve edeceğiz. Hangi "nokta" (sağdan) tutmak için size söyleyecektir. Sonra bunun sol (bulursa) bir nokta taşımak ve ondan önce her şeyi doğrayın.
Bir arama listesi olmadan, alt bölümleri (. Co, vb) (2 harfli TLD'lerini sahip) ülkeler için sadece ve AFAIK asla fazla 3 karakterden kendilerini ve her zaman harfler olduğu gerçeğini yararlanabilir muhtemelen yapabilirsiniz böylece regex deseni ile onları tanımak.
Edit: Nevermind, kamu eklerinin gerçek liste çok daha karmaşıktır. Sen, eki ne olduğunu anlamaya geri önceki nokta gidin ve sol trim bir arama tablosunu kullanmak için ihtiyacımız olacak. RegEx burada kötü bir çözümdür. Bunun yerine, sadece kesilmiş kısmını geri ekleyin, sonra bir maç vurmak kadar soldan bir anda bir noktalı kısmı kapalı lopping, bir Sözlük alan adı karşı o testi eklerin listesini saklamak.
Note: as pointed out in the comments, this method doesn't actually work in all cases. The reason for this is that some top-level domains do resolve to IP addresses, even if most do not. Therefore it's not possible to detect if a given name is top-level or pseudo-top-level domain name merely by checking if it has an IP address. Unfortunately, this probably means that the only solution is a lookup list, given how inconsistently treated top-level domains are in practice. strong>
I repeat: do not rely on the code below to work for you. I leave it here for educational purposes only. strong>
Bir arama listesi olmadan bunu yapmak için bir yol yoktur. Bu yöntem işe garanti oysa listesi, güvenilmez veya eksik olabilir:
<?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;
?>
Bu durumda, bu çıkışı 'robknight.org.uk' olacak. Bu. Com,. Edu,. Com.au. Ly veya ne olursa olsun diğer üst düzey alan üzerinde faaliyet konum için eşit derecede iyi çalışır.
Bu sağdan başlayarak ve uygulanabilir bir etki alanı adı olabilir gibi görünüyor ilk şey DNS kontrolü yaparak çalışır. Yukarıdaki örnekte, 'org.uk' ile başlar, ama bu bir gerçek etki alanı adı değil keşfeder, ama bir ccTLD olduğunu. Daha sonra hangi is geçerli, 'robknight.org.uk' kontrol geçer ve bu döndürür. Alan adı olsaydı, diyelim ki, 'www.php.net', geçerli bir alan adı olan 'php.net' işaretleyerek başlamış olurdu, ve döngü olmadan hemen o döndü olurdu. Ben de hiçbir geçerli etki alanı adı bulunursa, boş bir dize ('') iade edilecektir işaret olmalıdır.
Bu kod sayesinde DNS aramalarında alınan zaman zaman kısa bir boşluk içinde alan adlarının çok sayıda işlem için uygun olabilir, ama zaman kritik değil tek aramaları veya kod için gayet iyi.