Получить поддомен из URL - PullRequest
       58

Получить поддомен из URL

100 голосов
/ 14 ноября 2008

Поначалу получение субдомена из URL звучит просто.

http://www.domain.example

Сканирование для первого периода, а затем возврат того, что было после "http://" ...

Тогда вы помните

http://super.duper.domain.example

О. Итак, вы думаете, хорошо, найдите последний период, вернитесь на слово и получите все раньше!

Тогда вы помните

http://super.duper.domain.co.uk

И вы вернулись на круги своя. У кого-нибудь есть отличные идеи, кроме хранения списка всех TLD?

Ответы [ 15 ]

0 голосов
/ 29 марта 2012
echo tld('http://www.example.co.uk/test?123'); // co.uk

/**
 * http://publicsuffix.org/
 * http://www.alandix.com/blog/code/public-suffix/
 * http://tobyinkster.co.uk/blog/2007/07/19/php-domain-class/
 */
function tld($url_or_domain = null)
{
    $domain = $url_or_domain ?: $_SERVER['HTTP_HOST'];
    preg_match('/^[a-z]+:\/\//i', $domain) and 
        $domain = parse_url($domain, PHP_URL_HOST);
    $domain = mb_strtolower($domain, 'UTF-8');
    if (strpos($domain, '.') === false) return null;

    $url = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';

    if (($rules = file($url)) !== false)
    {
        $rules = array_filter(array_map('trim', $rules));
        array_walk($rules, function($v, $k) use(&$rules) { 
            if (strpos($v, '//') !== false) unset($rules[$k]);
        });

        $segments = '';
        foreach (array_reverse(explode('.', $domain)) as $s)
        {
            $wildcard = rtrim('*.'.$segments, '.');
            $segments = rtrim($s.'.'.$segments, '.');

            if (in_array('!'.$segments, $rules))
            {
                $tld = substr($wildcard, 2);
                break;
            }
            elseif (in_array($wildcard, $rules) or 
                    in_array($segments, $rules))
            {
                $tld = $segments;
            }
        }

        if (isset($tld)) return $tld;
    }

    return false;
}
0 голосов
/ 02 февраля 2011

Используйте URIBuilder затем получите атрибут URIBUilder.host разбить его на массив "." теперь у вас есть массив с выделенным доменом.

0 голосов
/ 14 ноября 2008

Беглый взгляд на список publicsuffix.org, похоже, что вы могли бы сделать разумное приближение, удалив последние три сегмента («сегмент» здесь означает раздел между двумя точками) из доменов, где последний сегмент равен двум длинных символов, при условии, что это код страны и будет дополнительно подразделен. Если последний сегмент - «мы», а второй-последний сегмент - также два символа, удалите последние четыре сегмента. Во всех остальных случаях удалите последние два сегмента. e.g.:

«пример» не состоит из двух символов, поэтому удалите «domain.example», оставив «www»

«пример» не состоит из двух символов, поэтому удалите «domain.example», оставив «super.duper»

«uk» - это два символа (но не «us»), поэтому удалите «domain.co.uk», оставив «super.duper»

«нас» - это два символа и это «мы», плюс «wy» также два символа, поэтому удалите «pvt.k12.wy.us», оставив «foo».

Обратите внимание, что, хотя это работает для всех примеров, которые я видел в ответах до сих пор, оно остается лишь разумным приближением. Это не совсем правильно, хотя я подозреваю, что оно настолько близко, насколько это возможно, без составления / получения фактического списка, который можно использовать для справки.

0 голосов
/ 14 ноября 2008

Список распространенных суффиксов (.co.uk, .com, и так далее) для удаления вместе с http: //, и тогда у вас будет только «sub.domain» для работы вместо « http://sub.domain.suffix", или, по крайней мере, это то, что я, вероятно, сделаю.

Самая большая проблема - это список возможных суффиксов. Многое, в конце концов.

0 голосов
/ 14 ноября 2008

Это не совсем точно, но вы могли бы получить полезный ответ, попытавшись извлечь кусочек домена по частям и проверив ответ, то есть извлечь 'http://uk', затем' http://co.uk', затем 'http://domain.co.uk'. Когда вы получаете ответ без ошибок, у вас есть домен, а остальное - субдомен.

Иногда вам просто нужно попробовать :)

Edit:

Том Лейс отмечает в комментариях, что некоторые домены настроены только на поддомене www, что даст нам неправильный ответ в приведенном выше тесте. Хорошая точка зрения! Может быть, лучшим подходом было бы проверить каждую часть с помощью 'http://www', а также' http://', и считать попадание в любой из них как совпадение для этого раздела имени домена? Нам все еще не хватало бы некоторых «альтернативных» соглашений, таких как «web.domain.com», но я некоторое время не сталкивался с одним из них:)

...