Разбор домена с 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.

Ответ 1

Отъезд 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-адресов.

Ответ 3

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

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

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 

Ответ 4

Код, предназначенный для работы на 100%, по-видимому, не сократил его для меня, я немного исправил этот пример, но нашел код, который не помогал, и проблемы с ним. поэтому я изменил его на несколько функций (чтобы сохранить запрос на список из mozilla все время и удалить систему cahce). Это было протестировано против набора из 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: exmaple.com
echo domain('www.example.uk.com') //outputs: exmaple.uk.com
echo domain('www.example.fr') //outputs: exmaple.fr

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

Ответ 5

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

Ответ 6

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

Но если вы хотите извлечь домен или его части, вам нужен пакет, который использует Public Suffix List. Да, вы можете использовать строковые функции arround 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'

Ответ 7

Вот код, который я сделал, что 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];
}

Ответ 8

Вы можете передать 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'

Ответ 9

$domain = parse_url($url, PHP_URL_HOST);
echo implode('.', array_slice(explode('.', $domain), -2, 2))

Ответ 10

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

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

Ответ 11

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

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

Ответ 12

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

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.domain.ltd, sub1.subn.domain.ltd приведет к: domain.ltd.

Ответ 14

Здесь мой искатель основан на приведенных выше ответах.

  • Выполнение класса (мне нравится Obj:)
  • он использует Curl, поэтому мы можем использовать HTTP-аутентификацию
  • это только ссылка на обход, которая относится к начальному домену URL.
  • он печатает код ответа 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();

Ответ 15

Я добавляю этот ответ позже, так как это ответ, который больше всего появляется в 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));
}

Ответ 16

Это будет работать очень хорошо, если входной 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

Ответ 17

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

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

Ответ 18

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

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