Как получить базовое доменное имя из URL с помощью PHP?

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

 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? Это необходимо для работы на всех платформах и хостах.

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

 $urlData = parse_url($url); $host = $urlData['host']; 

** Обновить **

Лучший способ, которым я могу думать, – это отобразить все TLD, которые вы хотите обработать, поскольку некоторые 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; 

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

EDIT: из-за комментария pjv я узнал, что австралийские доменные имена являются исключением, поскольку они позволяют использовать 5 TLD как SLD (com, net, org, asn, id): 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» – это субдомен «com»,

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

на http://www.google.com – «www» является субдоменом «google», который является субдоменом «com»,

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

исходя из этого предположения, эта функция вернет правильный «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. Это удобно для внутреннего использования, но это далеко от полного процесса проверки домена. Если вы пытаетесь использовать его таким образом, я рекомендую не использовать слишком много возможностей для соответствия недопустимым доменам.

Попробуйте использовать: 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]; 

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

 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.