2010-07-09 2 views
13

Мне нужно получить доменное имя из URL-адреса. Следующие примеры должны все вернуть google.com:Как получить базовое доменное имя из URL с помощью PHP?

google.com 
images.google.com 
new.images.google.com 
www.google.com 

Аналогично следующие URL-адреса должны все вернуть google.co.uk.

google.co.uk 
images.google.co.uk 
new.images.google.co.uk 
http://www.google.co.uk 

Я не решаются использовать регулярные выражения, потому что что-то вроде domain.com/google.com может возвращать неверные результаты.

Как я могу получить домен верхнего уровня, используя PHP? Это необходимо для работы на всех платформах и хостах.

+1

Это сложно. Для 'google.com' вас интересует доменное имя и доменное имя второго уровня. Для 'google.co.uk' вам нужны доменные имена домена и второго и третьего уровня. Нет определенного «базового имени», то, что вы подразумеваете под «базовым именем», различно для разных регистраторов/TLD. – deceze

+1

Я уверен, что вам нужно немного задержаться здесь, то, что вы просите, это есть ваш торт и иметь его тоже. Без списка TLD нет возможности различать co.uk и google.com, они оба являются именами хостов. –

+0

Я думаю, вы, ребята, правы, это не похоже, что все будет работать без большого количества кода – Rohan

ответ

16

Вы можете сделать это:

$urlData = parse_url($url); 

$host = $urlData['host']; 

** Обновление **

Лучшим способом я могу думать о том, чтобы иметь отображение всех доменов верхнего уровня которые вы хотите обработать, поскольку некоторые TLD могут быть сложными (co.uk).

// you can add more to it if you want 
$urlMap = array('com', 'co.uk'); 

$host = ""; 
$url = "http://www.google.co.uk"; 

$urlData = parse_url($url); 
$hostData = explode('.', $urlData['host']); 
$hostData = array_reverse($hostData); 

if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) { 
    $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0]; 
} elseif(array_search($hostData[0], $urlMap) !== FALSE) { 
    $host = $hostData[1] . '.' . $hostData[0]; 
} 

echo $host; 
3

Попробуйте использовать: http://php.net/manual/en/function.parse-url.php. Нечто подобное должно работать:

$urlParts = parse_url($yourUrl); 
$hostParts = explode('.', $urlParts['host']); 
$hostParts = array_reverse($hostParts); 
$host = $hostParts[1] . '.' . $hostParts[0]; 
+1

Это сломается, если у вас есть что-то вроде этого: http: //www.google.co.uk - в этом случае он вернет «co.uk». – xil3

+1

Действительно, единственный способ получить эту сортировку - это использовать список TLD. –

-3

Используйте эту функцию:

function getHost($url){ 
    if (strpos($url,"http://")){ 
     $httpurl=$url; 
    } else { 
     $httpurl="http://".$url; 
    } 
    $parse = parse_url($httpurl); 
    $domain=$parse['host']; 

    $portion=explode(".",$domain); 
    $count=sizeof($portion)-1; 
    if ($count>1){ 
     $result=$portion[$count-1].".".$portion[$count]; 
    } else { 
     $result=$domain; 
    } 
    return $result; 
} 

Ответьте на все варианты примера URL.

5

Домены верхнего уровня и домены второго уровня могут иметь длину 2 символа, но зарегистрированный субдомен должен иметь длину не менее 3 символов.

EDIT: из-за комментария pjv я узнал, что австралийские доменные имена являются исключением, поскольку они позволяют 5 TLDs как SLD (com, net, org, asn, id) example: somedomain.com.au. Я предполагаю, что com.au является государственным доменным именем, которое «разделяет». так что технически «com.au» все равно будет «базовым доменом», но это не полезно.

EDIT: существует 47 952 возможных трехбуквенных доменных имени (шаблон: [a-zA-Z0-9] [a-zA-Z0-9 -] [a-zA-Z0-9] или 36 * 37 * 36) в сочетании с 8 наиболее распространенными TLDS (com, org и т. Д.) У нас есть 383 616 возможностей - даже не добавляя во весь диапазон TLD. Однобуквенные и двухбуквенные имена доменов все еще существуют, но недействительны в будущем.

в google.com - «Google» является поддомен «ком»

в google.co.uk - «Google» является поддомен «со», который, в свою очередь, является подобласть «uk» или домен второго уровня, так как «co» также является допустимым доменом верхнего уровня.

на www.google.com - «www» является поддоменом «google», который является поддоменом из «ком»

«co.uk» не является действительным хозяином, потому что нет допустимого доменного имени

собирается с этим assumpt иона эта функция вернет правильный «basedomain» почти во всех случаях, не требуя «карты url».

Если вы оказались в одном из редких случаев, возможно, вы можете изменить это, чтобы удовлетворить особые потребности ...

EDIT: вы должны передать доменную строку в виде URL-адреса с его протоколом (http: //, ftp: // и т. Д.) Или parse_url() не будет считать его действительным URL-адресом (если вы не хотите изменять код, чтобы вести себя по-разному)

function basedomain($str = '') 
{ 
    // $str must be passed WITH protocol. ex: http://domain.com 
    $url = @parse_url($str); 
    if (empty($url['host'])) return; 
    $parts = explode('.', $url['host']); 
    $slice = (strlen(reset(array_slice($parts, -2, 1))) == 2) && (count($parts) > 2) ? 3 : 2; 
    return implode('.', array_slice($parts, (0 - $slice), $slice)); 
} 

, если вам нужно, чтобы быть точным использование fopen или curl открыть этот URL: http://data.iana.org/TLD/tlds-alpha-by-domain.txt

затем читать строки в массив и использовать его для сравнения частей домена

EDIT: чтобы для австралийских доменов:

function au_basedomain($str = '') 
{ 
    // $str must be passed WITH protocol. ex: http://domain.com 
    $url = @parse_url($str); 
    if (empty($url['host'])) return; 
    $parts = explode('.', $url['host']); 
    $slice = (strlen(reset(array_slice($parts, -2, 1))) == 2) && (count($parts) > 2) ? 3 : 2; 
    if (preg_match('/\.(com|net|asn|org|id)\.au$/i', $url['host'])) $slice = 3; 
    return implode('.', array_slice($parts, (0 - $slice), $slice)); 
} 

ВАЖНЫЕ ДОПОЛНИТЕЛЬНЫЕ ПРИМЕЧАНИЯ: Я не использую эту функцию для проверки доменов. Это общий код, который я использую только для извлечения базового домена для сервера, на котором он запущен, от глобального $_SERVER['SERVER_NAME'] для использования в различных внутренних сценариях. Учитывая, что я когда-либо работал на сайтах в США, я никогда не сталкивался с австралийскими вариантами, о которых спрашивал pjv. Это удобно для внутреннего использования, но это далеко от полного процесса проверки домена. Если вы пытаетесь использовать его таким образом, я рекомендую не использовать слишком много возможностей для соответствия недопустимым доменам.

+1

Если вы измените это 'strlen() == 2' на' <= 3', вы поймаете 99% доменов, сохраните субдомены на localhost и еще что-то еще. Вот моя ревизия: https://gist.github.com/anonymous/fe77c97e632675411c3c – Mahn

+0

Нет, исправление не работает. Он должен быть равен == 2, потому что <= 3 будет соответствовать, когда рядом с последней частью будет 3 - что мы не хотим делать. Мы хотим, чтобы он вернул «google.com» с «www.google.com» или «mail.google.com», и мы хотим, чтобы он вернул «google.co.uk» с «www.google.co.uk» или "mail.google.co.uk" – aequalsb

+0

@Mahn Кроме того, в вашей ревизии есть много дополнительных битов - ненужные присваивания переменных и вложение ненужных состояний. Больше кода и нежелательного результата - вы тщательно проверили свою ревизию? – aequalsb

0

Смешивание с ответом xil3 Это я должен проверить localhost, а также ip, так что вы также можете работать в среде разработки.
Вы все равно должны определить, какие TLD вы хотите использовать. кроме этого все работает нормально.

<?php 
function getTopLevelDomain($url){ 
    $urlData = parse_url($url); 
    $urlHost = isset($urlData['host']) ? $urlData['host'] : ''; 
    $isIP = (bool)ip2long($urlHost); 
    if($isIP){ /** To check if it's ip then return same ip */ 
     return $urlHost; 
    } 
    /** Add/Edit you TLDs here */ 
    $urlMap = array('com', 'com.pk', 'co.uk'); 

    $host = ""; 
    $hostData = explode('.', $urlHost); 
    if(isset($hostData[1])){ /** To check "localhost" because it'll be without any TLDs */ 
     $hostData = array_reverse($hostData); 

     if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) { 
      $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0]; 
     } elseif(array_search($hostData[0], $urlMap) !== FALSE) { 
      $host = $hostData[1] . '.' . $hostData[0]; 
     } 
     return $host; 
    } 
    return ((isset($hostData[0]) && $hostData[0] != '') ? $hostData[0] : 'error no domain'); /* You can change this error in future */ 
} 
?> 

вы можете использовать его как этот

$string = 'http://googl.com.pk'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com.pk:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com.pk'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com.pk:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://192.168.0.101:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://192.168.0.101'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://localhost'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'https;//'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = ''; 
echo getTopLevelDomain($string) . '<br>'; 

Вы получите результат в строку, как этот

googl.com.pk 
googl.com.pk 
googl.com 
googl.com 
googl.com.pk 
googl.com.pk 
googl.com 
googl.com 
192.168.0.101 
192.168.0.101 
localhost 
error no domain 
error no domain 
Смежные вопросы