Извлечение домена из URL в PHP


мне нужно построить функцию, которая анализирует домен из URL.

так, с

http://google.com/dhasjkdas/sadsdds/sdda/sdads.html

или

http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html

он должен вернуть google.com

С

http://google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html

он должен вернуть google.co.uk.

18 114
php

18 ответов:

проверить parse_url():

$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$parse = parse_url($url);
echo $parse['host']; // prints 'google.com'

parse_url не обрабатывает очень плохо искаженные URL-адреса очень хорошо, но это нормально, если вы обычно ожидаете приличные URL-адреса.

$domain = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST));

это вернет google.com для обоих http://google.com/... и http://www.google.com/...

от http://us3.php.net/manual/en/function.parse-url.php#93983

по какой-то странной причине, parse_url возвращает хозяину (исх. example.com) как путь, когда схема не предоставляется в входной URL-адрес. Так что я написал быстро функция для получения реального хоста:

function getHost($Address) { 
   $parseUrl = parse_url(trim($Address)); 
   return trim($parseUrl['host'] ? $parseUrl['host'] : array_shift(explode('/', $parseUrl['path'], 2))); 
} 

getHost("example.com"); // Gives example.com 
getHost("http://example.com"); // Gives example.com 
getHost("www.example.com"); // Gives www.example.com 
getHost("http://example.com/xyz"); // Gives example.com 

код, который должен был работать на 100%, похоже, не сократил его для меня, я немного исправил пример, но нашел код, который не помогал и проблемы с ним. поэтому я изменил его на пару функций (чтобы сохранить запрос на список из Mozilla все время и удалить систему кэша). Это было протестировано против набора из 1000 URL-адресов и, казалось, работало.

function domain($url)
{
    global $subtlds;
    $slds = "";
    $url = strtolower($url);

    $host = parse_url('http://'.$url,PHP_URL_HOST);

    preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
    foreach($subtlds as $sub){
        if (preg_match('/\.'.preg_quote($sub).'$/', $host, $xyz)){
            preg_match("/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/", $host, $matches);
        }
    }

    return @$matches[0];
}

function get_tlds() {
    $address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
    $content = file($address);
    foreach ($content as $num => $line) {
        $line = trim($line);
        if($line == '') continue;
        if(@substr($line[0], 0, 2) == '/') continue;
        $line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line);
        if($line == '') continue;  //$line = '.'.$line;
        if(@$line[0] == '.') $line = substr($line, 1);
        if(!strstr($line, '.')) continue;
        $subtlds[] = $line;
        //echo "{$num}: '{$line}'"; echo "<br>";
    }

    $subtlds = array_merge(array(
            'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk', 
            'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au',
            'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au'
        ), $subtlds);

    $subtlds = array_unique($subtlds);

    return $subtlds;    
}

тогда используйте его как

$subtlds = get_tlds();
echo domain('www.example.com') //outputs: example.com
echo domain('www.example.uk.com') //outputs: example.uk.com
echo domain('www.example.fr') //outputs: example.fr

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

function get_domain($url = SITE_URL)
{
    preg_match("/[a-z0-9\-]{1,63}\.[a-z\.]{2,6}$/", parse_url($url, PHP_URL_HOST), $_domain_tld);
    return $_domain_tld[0];
}

get_domain('http://www.cdl.gr'); //cdl.gr
get_domain('http://cdl.gr'); //cdl.gr
get_domain('http://www2.cdl.gr'); //cdl.gr

Если вы хотите извлечь хозяина из строки http://google.com/dhasjkdas/sadsdds/sdda/sdads.html, использование parse_url() является приемлемым решением для вас.

но если вы хотите извлечь домен или его части, вам нужен пакет, который использует Публичный Список Суффиксов. Да, вы можете использовать строковые функции вокруг parse_url (), но иногда это приведет к неверным результатам.

Я рекомендую TLDExtract для разбора домена, вот пример кода, который показывает diff:

$extract = new LayerShifter\TLDExtract\Extract();

# For 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'

$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';

parse_url($url, PHP_URL_HOST); // will return google.com

$result = $extract->parse($url);
$result->getFullHost(); // will return 'google.com'
$result->getRegistrableDomain(); // will return 'google.com'
$result->getSuffix(); // will return 'com'

# For 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html'

$url = 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html';

parse_url($url, PHP_URL_HOST); // will return 'search.google.com'

$result = $extract->parse($url);
$result->getFullHost(); // will return 'search.google.com'
$result->getRegistrableDomain(); // will return 'google.com'

вот код, который я сделал, что 100% находит только доменное имя, так как он принимает Mozilla sub tlds для учета. Единственное, что вам нужно проверить, это то, как вы делаете кэш этого файла, поэтому вы не запрашиваете mozilla каждый раз.

по какой-то странной причине Домены вроде co.uk их нет в списке, поэтому вам придется сделать некоторые взломы и добавить их вручную. Его не самое чистое решение, но я надеюсь, что это поможет кому-то.

//=====================================================
static function domain($url)
{
    $slds = "";
    $url = strtolower($url);

            $address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
    if(!$subtlds = @kohana::cache('subtlds', null, 60)) 
    {
        $content = file($address);
        foreach($content as $num => $line)
        {
            $line = trim($line);
            if($line == '') continue;
            if(@substr($line[0], 0, 2) == '/') continue;
            $line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line);
            if($line == '') continue;  //$line = '.'.$line;
            if(@$line[0] == '.') $line = substr($line, 1);
            if(!strstr($line, '.')) continue;
            $subtlds[] = $line;
            //echo "{$num}: '{$line}'"; echo "<br>";
        }
        $subtlds = array_merge(Array(
            'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk', 
            'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au',
            'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au',
            ),$subtlds);

        $subtlds = array_unique($subtlds);
        //echo var_dump($subtlds);
        @kohana::cache('subtlds', $subtlds);
    }


    preg_match('/^(http:[\/]{2,})?([^\/]+)/i', $url, $matches);
    //preg_match("/^(http:\/\/|https:\/\/|)[a-zA-Z-]([^\/]+)/i", $url, $matches);
    $host = @$matches[2];
    //echo var_dump($matches);

    preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
    foreach($subtlds as $sub) 
    {
        if (preg_match("/{$sub}$/", $host, $xyz))
        preg_match("/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/", $host, $matches);
    }

    return @$matches[0];
}

вы можете передать PHP_URL_HOST в функцию parse_url в качестве второго параметра

$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$host = parse_url($url, PHP_URL_HOST);
print $host; // prints 'google.com'
$domain = parse_url($url, PHP_URL_HOST);
echo implode('.', array_slice(explode('.', $domain), -2, 2))

Я обнаружил, что решение @philfreo (ссылка из php.net) довольно хорошо, чтобы получить прекрасный результат, но в некоторых случаях он показывает сообщение php "уведомление" и "строгие стандарты". Вот фиксированная версия этого кода.

function getHost($url) { 
   $parseUrl = parse_url(trim($url)); 
   if(isset($parseUrl['host']))
   {
       $host = $parseUrl['host'];
   }
   else
   {
        $path = explode('/', $parseUrl['path']);
        $host = $path[0];
   }
   return trim($host); 
} 

echo getHost("http://example.com/anything.html");           // example.com
echo getHost("http://www.example.net/directory/post.php");  // www.example.net
echo getHost("https://example.co.uk");                      // example.co.uk
echo getHost("www.example.net");                            // example.net
echo getHost("subdomain.example.net/anything");             // subdomain.example.net
echo getHost("example.net");                                // example.net

parse_url не работает для меня. Он только вернул путь. Переход к основам с помощью php5. 3+:

$url  = str_replace('http://', '', strtolower( $s->website));
if (strpos($url, '/'))  $url = strstr($url, '/', true);

я отредактировал для вас:

function getHost($Address) { 
    $parseUrl = parse_url(trim($Address));
    $host = trim($parseUrl['host'] ? $parseUrl['host'] : array_shift(explode('/', $parseUrl['path'], 2))); 

    $parts = explode( '.', $host );
    $num_parts = count($parts);

    if ($parts[0] == "www") {
        for ($i=1; $i < $num_parts; $i++) { 
            $h .= $parts[$i] . '.';
        }
    }else {
        for ($i=0; $i < $num_parts; $i++) { 
            $h .= $parts[$i] . '.';
        }
    }
    return substr($h,0,-1);
}

все типы url (www.домен.ltd, sub1.subn.домен.ltd приведет к: домен.ооо.

проверить parse_url ()

вот мой гусеничный движок, основанный на приведенных выше ответах.

  1. реализация класса ( мне нравится Obj :)
  2. он использует Curl поэтому мы можем использовать http auth требуется
  3. он только ползать ссылке, которая относится к началу юзабилити домен домен
  4. он печатает код ответа заголовка http ( полезно для проверки проблем на сайте)

КОД КЛАССА ОБХОДА

class crawler
{
    protected $_url;
    protected $_depth;
    protected $_host;

    public function __construct($url, $depth = 5)
    {
        $this->_url = $url;
        $this->_depth = $depth;
        $parse = parse_url($url);
        $this->_host = $parse['host'];
    }

    public function run()
    {
        $this->crawl_page($this->_url, $this->_depth = 5);
    }

    public function crawl_page($url, $depth = 5)
    {
        static $seen = array();
        if (isset($seen[$url]) || $depth === 0) {
            return;
        }
        $seen[$url] = true;
        list($content, $httpcode) = $this->getContent($url);

        $dom = new DOMDocument('1.0');
        @$dom->loadHTML($content);
        $this->processAnchors($dom, $url, $depth);

        ob_end_flush();
        echo "CODE::$httpcode, URL::$url <br>";
        ob_start();
        flush();
        // echo "URL:", $url, PHP_EOL, "CONTENT:", PHP_EOL, $dom->saveHTML(), PHP_EOL, PHP_EOL;
    }

    public function processAnchors($dom, $url, $depth)
    {
        $anchors = $dom->getElementsByTagName('a');
        foreach ($anchors as $element) {
            $href = $element->getAttribute('href');
            if (0 !== strpos($href, 'http')) {
                $path = '/' . ltrim($href, '/');
                if (extension_loaded('http')) {
                    $href = http_build_url($url, array('path' => $path));
                } else {
                    $parts = parse_url($url);
                    $href = $parts['scheme'] . '://';
                    if (isset($parts['user']) && isset($parts['pass'])) {
                        $href .= $parts['user'] . ':' . $parts['pass'] . '@';
                    }
                    $href .= $parts['host'];
                    if (isset($parts['port'])) {
                        $href .= ':' . $parts['port'];
                    }
                    $href .= $path;
                }
            }
            // Crawl only link that belongs to the start domain
            if (strpos($href, $this->_host) !== false)
                $this->crawl_page($href, $depth - 1);
        }
    }

    public function getContent($url)
    {
        $handle = curl_init($url);
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);

        /* Get the HTML or whatever is linked in $url. */
        $response = curl_exec($handle);

        /* Check for 404 (file not found). */
        $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
        if ($httpCode == 404) {
            /* Handle 404 here. */
        }

        curl_close($handle);
        return array($response, $httpCode);
    }
}

// USAGE
$startURL = 'http://YOUR_START_ULR';
$depth = 2;
$crawler = new crawler($startURL, $depth);
$crawler->run();

я добавляю этот ответ поздно, так как это ответ, который появляется всего на Google...

вы можете использовать PHP...

$url = "www.google.co.uk";
$host = parse_url($url, PHP_URL_HOST);
// $host == "www.google.co.uk"

чтобы захватить хоста а не отдельный домен, к которому хозяин относится. (Например,www.google.co.uk - это хозяин, но google.co.uk - это частный домен)

чтобы захватить частный домен, вам нужно знать список публичных суффиксов, к которым можете Регистрация частного домена. Этот список оказывается, куратор Mozilla в https://publicsuffix.org/

приведенный ниже код работает, когда массив публичных суффиксов уже создан. Просто позвоните

$domain = get_private_domain("www.google.co.uk");

с оставшимся кодом...

// find some way to parse the above list of public suffix
// then add them to a PHP array
$suffix = [... all valid public suffix ...];

function get_public_suffix($host) {
  $parts = split("\.", $host);
  while (count($parts) > 0) {
    if (is_public_suffix(join(".", $parts)))
      return join(".", $parts);

    array_shift($parts);
  }

  return false;
}

function is_public_suffix($host) {
  global $suffix;
  return isset($suffix[$host]);
}

function get_private_domain($host) {
  $public = get_public_suffix($host);
  $public_parts = split("\.", $public);
  $all_parts = split("\.", $host);

  $private = [];

  for ($x = 0; $x < count($public_parts); ++$x) 
    $private[] = array_pop($all_parts);

  if (count($all_parts) > 0)
    $private[] = array_pop($all_parts);

  return join(".", array_reverse($private));
}

это, как правило, работает очень хорошо, если входной URL-адрес не является полным мусором. Он удаляет поддомен.

$host = parse_url( $Row->url, PHP_URL_HOST );
$parts = explode( '.', $host );
$parts = array_reverse( $parts );
$domain = $parts[1].'.'.$parts[0];

пример

вход: http://www2.website.com:8080/some/file/structure?some=parameters

выход: website.com

объединение ответов worldofjr и Аликс Аксель в одну небольшую функцию, которая будет обрабатывать большинство случаев использования:

function get_url_hostname($url) {

    $parse = parse_url($url);
    return str_ireplace('www.', '', $parse['host']);

}

get_url_hostname('http://www.google.com/example/path/file.html'); // google.com

просто использовать, как показано ниже ...

<?php
   echo $_SERVER['SERVER_NAME'];
?>