URL에서 도메인 파싱


144

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.



9
@LightnessRacesinOrbit 이것은 단지 "매뉴얼을 보는 것"그 이상입니다. PHP 는 domain이 아닌 호스트를parse_url() 반환 합니다 .
MrWhite

1
@ w3dk : 그것은 여전히 ​​환상적인 출발점이되었으므로이 질문 parse_url은 모호한 "무엇을 할 수 있는가" 가 아니라 그 한계에 관한 것입니다.
궤도에서 가벼움 레이스

5
@LightnessRacesinOrbit은 (는) 자신의 평판을 감안할 때 귀하의 방어를 불쾌하게 여깁니다. 더 간단히 말하면 질문을 완전히 읽지 않았다는 것을 인정할 수 있습니다.
Andy Jones

4
@LightnessRacesinOrbit 반드시 그런 것은 아닙니다. support.suso.com/supki/…
가을 레너드

답변:


297

체크 아웃 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을 기대하면 좋습니다.


35
parse_url ()이하지 않는 한 가지는 도메인 만 반환하는 것입니다. www.google.com 또는 www.google.co.uk를 추가하면 호스트도 반환됩니다. 그것에 대한 제안?
Gavin M. Roy


6
parse_url하위 도메인을 처리하지 않지만 Purl
Damien

1
parse_url()대시가 잘못 포함 된 도메인으로 URL을 구문 분석 할 수 있습니다. 확실한 증거를 찾을 수 없지만 이 버그를 확인하십시오 . 내부적으로 FILTER_VALIDATE_URL사용합니다 parse_url().
Xedin 알 수 없음

8
또는 단순히 : 다른 것을 print parse_url($url, PHP_URL_HOST))위해 $parse배열이 필요하지 않은 경우 .
rybo111

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

이것은을 반환 google.com모두 http://google.com/ ... 그리고 http://www.google.com/ ...


18
"server.google.com"또는 "www3.google.com"을 입력해도 서버가 여전히 반환되므로 ...
patrick

모든 하위 도메인이 www 인 것은 아닙니다. crawl-66-249-66-1.googlebot.com, myblog.blogspot.com은 몇 가지 예입니다.
rafark

23

에서 http://us3.php.net/manual/en/function.parse-url.php#93983

이상한 이유로 parse_url은 입력 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 

hostand 같은 문자열을 인용하는 것을 잊지 마십시오 path.
Gumbo

1
example.com을 사용하면 php에 알림이 표시됩니다. Message: Undefined index: host이 문제를 해결하기위한 아이디어가 있습니까?
Zim3r

1
불행히도 하위 도메인은 여전히이 접근 방식에 포함되어 있습니다 (예제 3 참조).
jenlampton

1
@ Zim3r 삼항의 첫 부분을로 변경하십시오 !empty($parseUrl['host']).
Demonslay3351 년

LOL 구성표가 없으면 URL이 아닙니다.
miken32

12

100 % 작동하도록 의도 된 코드는 나를 위해 그것을 잘라 내지 않는 것 같습니다. 나는 예제를 조금 패치했지만 도움이되지 않고 문제가있는 코드를 찾았습니다. 그래서 몇 가지 기능으로 변경했습니다 (모질라에게 항상 목록을 요구하고 캐시 시스템을 제거하기 위해). 이것은 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

나는 이것을 수업으로 바꾸어야했지만 시간이 없었 음을 알고있다.


11
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

example.com // 틀린 예 : 빈 문자열 example.com // 틀린 예 : example.com www.example.com // 틀린 예 : 빈 끈 example.com/xyz // 틀린 예 : example.com
jenlampton

이것은 훌륭한 답변이며 더 많은 가치가 있습니다. 이 줄을 함수의 첫 번째 줄로 추가하면 MangeshSathe 및 jenlampton의 문제도 해결할 수 있습니다. if ((substr ($ url, 0, strlen ( 'http : //')) <> 'http : //' ) && (substr ($ url, 0, strlen ( 'https : //')) <> 'https : //')) $ url = 'http : //'.$url;
Rick

4

string http://google.com/dhasjkdas/sadsdds/sdda/sdads.html에서 호스트를 추출하려면 parse_url () 사용법이 적합합니다.

그러나 도메인이나 그 부분을 추출하려면 Public Suffix List 를 사용하는 패키지가 필요합니다 . 예, parse_url () 문자열 함수 arround를 사용할 수 있지만 때로는 잘못된 결과가 생성됩니다.

도메인 구문 분석을 위해 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'

이 제안에 감사드립니다. 나는 간단한 작업으로 보이는 것에 대해 다른 라이브러리를 추가하는 것을 싫어 하지만, readme에서이 인용문이 나에게 적용되는 것을 보았습니다. "모두가 이것을 잘못 얻습니다. 예를 들어 .com 도메인을 생각하고있는 경우에만 마지막 2 개 요소를 사용하는 것이 먼 길을갑니다 예 를 들어 구문 분석 forums.bbc.co.uk 를 생각해보십시오. 'bbc'와 'co.uk'대신 'uk'를 TLD로 사용합니다. "
Demonslay3351 년

우리가 사랑하는 .co.uk 도메인에서 일어나고 싶지 않은 점에서 점을 나누는 결과는 실제로 올바른 결과이며, co는 두 번째 수준이며, uk는 최상위 수준입니다. 웹 마스터는 종종 그것을 깨닫지 못합니다.
Chris

4

@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

2

다음은 100 % 도메인 이름 만 찾도록 만든 코드입니다. mozilla 하위 속성을 고려하기 때문입니다. 확인해야 할 것은 파일을 캐시하는 방법뿐이므로 매번 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];
}

도메인 co.uk이 목록에없는 이유는 도메인 이 아닌 TLD 목록이기 때문입니다. 이 답변이 작성된 이후 ccTLD가 많이 변경되었습니다. 주목할만한 점 : ".uk 바로 아래의 새로운 등록은 2014 년 6 월 10 일 08:00 BST 이후 Nominet에 의해 접수되었지만 이미 .co.uk, .org.uk, .me.uk를 보유한 기존 고객에게는 예약 기간이 있습니다 , .net.uk, .ltd.uk 또는 .plc.uk 도메인은 2019 년 6 월 10 일 07:59 BST까지 운영되는 해당 .uk 도메인을 청구합니다 . " ( 출처 )
ashleedawg

2

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'

2
이것은 본질적으로 위의 답변과 동일하지만 문제는 도메인을 필요로하며 호스트 와 반드시 동일하지는 않습니다 .
MrWhite

scheme에 대해서는 위의 주석을 참조하십시오. 이상한 이유로 parse_url은 입력 URL에 스키마가 제공되지 않은 경우 호스트 (예 : example.com)를 경로로 반환합니다. 따라서 실제 호스트를 얻는 빠른 기능을 작성했습니다.
jenlampton


2

허용 된 솔루션을 다음과 같이 바꾸십시오.

parse_url ()은 항상 모든 하위 도메인을 포함하므로이 함수는 도메인 이름을 잘 분석하지 않습니다. 여기 몇 가지 예가 있어요.

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

echo parse_url('https://subdomain.example.com/foo/bar', PHP_URL_HOST);
// Output: subdomain.example.com

echo parse_url('https://subdomain.example.co.uk/foo/bar', PHP_URL_HOST);
// Output: subdomain.example.co.uk

대신이 실용적인 솔루션을 고려할 수 있습니다. 예를 들어, 'sos.state.oh.us'와 같은 하위 도메인은 다루지 않습니다.

function getDomain($url) {
    $host = parse_url($url, PHP_URL_HOST);

    if(filter_var($host,FILTER_VALIDATE_IP)) {
        // IP address returned as domain
        return $host; //* or replace with null if you don't want an IP back
    }

    $domain_array = explode(".", str_replace('www.', '', $host));
    $count = count($domain_array);
    if( $count>=3 && strlen($domain_array[$count-2])==2 ) {
        // SLD (example.co.uk)
        return implode('.', array_splice($domain_array, $count-3,3));
    } else if( $count>=2 ) {
        // TLD (example.com)
        return implode('.', array_splice($domain_array, $count-2,2));
    }
}

// Your domains
    echo getDomain('http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'); // google.com
    echo getDomain('http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html'); // google.com
    echo getDomain('http://google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html'); // google.co.uk

// TLD
    echo getDomain('https://shop.example.com'); // example.com
    echo getDomain('https://foo.bar.example.com'); // example.com
    echo getDomain('https://www.example.com'); // example.com
    echo getDomain('https://example.com'); // example.com

// SLD
    echo getDomain('https://more.news.bbc.co.uk'); // bbc.co.uk
    echo getDomain('https://www.bbc.co.uk'); // bbc.co.uk
    echo getDomain('https://bbc.co.uk'); // bbc.co.uk

// IP
    echo getDomain('https://1.2.3.45');  // 1.2.3.45

마지막으로 Jeremy Kendall의 PHP 도메인 파서를 사용하면 URL에서 도메인 이름을 구문 분석 할 수 있습니다. 리그 URI 호스트 이름 파서 도 작업을 수행합니다.


안녕하세요, 이것은 좋지만 IP 주소에서는 작동하지 않습니다. 여전히 훌륭합니다.
MeCe

1

parse_url이 작동하지 않았습니다. 경로 만 반환했습니다. php5.3 +를 사용하여 기본으로 전환 :

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

1

나는 당신을 위해 편집했습니다 :

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.


1

이 답변은 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개인 도메인입니다)

개인 도메인을 확보하려면 개인 도메인 등록 할 수 있는 공용 접미사 목록을 알아야 합니다. 이 목록은 https://publicsuffix.org/ 에서 Mozilla에 의해 선별됩니다.

아래 코드는 공개 접미어 배열이 이미 만들어 졌을 때 작동합니다. 간단히 전화

$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));
}

내 테스트에 따라 parse_url은 올바른 형식의 URL이 필요합니다. 'www.someDomain.com/path'를 제공하면 null이 반환됩니다. 따라서 http 또는 https와 같은 프로토콜이 존재할 것으로 예상합니다.
Andy

0

입력 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


0

worldofjrAlix 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

이것은 제한적인 솔루션입니다
MGE

0
function getTrimmedUrl($link)
{
    $str = str_replace(["www.","https://","http://"],[''],$link);
    $link = explode("/",$str);
    return strtolower($link[0]);                
}


-6

다음과 같이 사용하십시오 ...

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

1
이것은 서버가 도메인을 검색하려는 URL이라고 가정합니다. 그렇지 않습니다.
오버 코딩
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.