113

Tôi cần xây dựng một chức năng phân tích tên miền từ một URL.

Vì vậy

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

hoặc là

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

nó sẽ trở lại google.com

với

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

nó sẽ trả về google.co.uk.

|
247

Kiểm tra parse_url():

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

parse_url không xử lý các url thực sự rất tệ, nhưng vẫn ổn nếu bạn thường mong đợi các url tốt.

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

Điều này sẽ trả lại google.comcho cả http://google.com/ ... và http://www.google.com/ ...

|
20

Từ http://us3.php.net/manual/en/feft.parse-url.php#93983

vì một số lý do kỳ lạ, parse_url trả về máy chủ (ví dụ: ví dụ.com) là đường dẫn khi không có lược đồ nào được cung cấp trong url đầu vào. Vì vậy, tôi đã viết một chức năng nhanh chóng để có được máy chủ thực sự:

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 
|
10

Mã có nghĩa là hoạt động 100% dường như không cắt nó cho tôi, tôi đã vá ví dụ một chút nhưng tìm thấy mã không giúp ích và gặp vấn đề với nó. vì vậy tôi đã thay đổi nó thành một vài chức năng (để lưu yêu cầu danh sách từ Mozilla mọi lúc và xóa hệ thống bộ đệm). Điều này đã được thử nghiệm với một bộ 1000 URL và dường như hoạt động.

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

Sau đó sử dụng nó như

$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

Tôi biết tôi nên biến điều này thành một lớp học, nhưng không có thời gian.

|
7
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
|
4

Nếu bạn muốn trích xuất máy chủ từ chuỗi http://google.com/dhasjkdas/sadsdds/sdda/sdads.html, việc sử dụng parse_url () là giải pháp chấp nhận được cho bạn.

Nhưng nếu bạn muốn trích xuất tên miền hoặc các phần của nó, bạn cần gói sử dụng Danh sách hậu tố công cộng . Có, bạn có thể sử dụng các hàm chuỗi arround parse_url (), nhưng đôi khi nó sẽ tạo ra kết quả không chính xác.

Tôi khuyên bạn nên TLDExtract để phân tích tên miền, đây là mã mẫu hiển thị 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'
|
  • 1

    Cảm ơn bạn rất nhiều vì lời đề nghị này. Tôi ghét thêm một thư viện khác cho những gì dường như là một nhiệm vụ đơn giản, nhưng sau đó tôi thấy câu trích dẫn này trên readme của họ áp dụng cho tôi: "Mọi người đều hiểu sai. Chia tách trên '.' và sử dụng 2 yếu tố cuối cùng chỉ đi một chặng đường dài nếu bạn đang nghĩ về các tên miền đơn giản như .com. Hãy suy nghĩ phân tích diễn đàn.bbc.co.uk chẳng hạn: phương pháp phân tách ngây thơ ở trên sẽ cho bạn 'đồng' làm tên miền và 'uk' là TLD, thay vì 'bbc' và 'co.uk' tương ứng. "

    – Dương Ngọc Tuấn 18:58:08 01/01/2017
  • 1

    Kết quả cho việc phân tách các dấu chấm trong khi không phải là những gì chúng ta muốn xảy ra trên các miền .co.uk yêu quý của chúng tôi, thực sự là kết quả chính xác, đồng là cấp độ thứ hai với uk là cấp cao nhất. Quản trị trang web thường không nhận ra điều đó.

    – Hoàng Thúy Giang 22:06:51 27/10/2017
2

Tôi đã thấy rằng giải pháp của @ philfreo (được tham chiếu từ php.net) khá tốt để có kết quả tốt nhưng trong một số trường hợp, nó hiển thị thông báo "thông báo" và "Tiêu chuẩn nghiêm ngặt" của php. Đây là một phiên bản cố định của mã này.

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
$domain = parse_url($url, PHP_URL_HOST);
echo implode('.', array_slice(explode('.', $domain), -2, 2))
|
2

Bạn có thể truyền PHP_URL_HOST vào hàm parse_url làm tham số thứ hai

$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$host = parse_url($url, PHP_URL_HOST);
print $host; // prints 'google.com'
|
  • 1

    Điều này về cơ bản giống như câu trả lời ở trên, tuy nhiên, câu hỏi là yêu cầu tên miền , không nhất thiết phải giống như máy chủ lưu trữ .

    – Bùi Bá Thành 14:32:47 25/04/2016
  • 1

    xem bình luận ở trên về lược đồ: vì một số lý do kỳ lạ, parse_url trả về máy chủ (ví dụ: ví dụ.com) là đường dẫn khi không có lược đồ nào được cung cấp trong url đầu vào. Vì vậy, tôi đã viết một chức năng nhanh chóng để có được máy chủ thực sự:

    – Võ Kim Cương 21:34:33 26/11/2016
2

Đây là mã tôi đã thực hiện mà 100% chỉ tìm thấy tên miền, vì phải có tài khoản phụ mozilla vào tài khoản. Điều duy nhất bạn phải kiểm tra là cách bạn tạo bộ đệm của tệp đó, vì vậy bạn không truy vấn mozilla mỗi lần.

Vì một số lý do lạ, các tên miền như co.uk không có trong danh sách, vì vậy bạn phải thực hiện một số hack và thêm chúng theo cách thủ công. Giải pháp không sạch nhất của nó nhưng tôi hy vọng nó sẽ giúp được ai đó.

//=====================================================
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];
}
|
  • 1

    Lý do tên miền co.ukkhông có trong danh sách, là vì đó là danh sách của TLD chứ không phải tên miền. Các ccTLD đã thay đổi rất nhiều kể từ khi câu trả lời này được viết. Đáng chú ý: "Đăng ký mới trực tiếp dưới .uk đã được Nominet chấp nhận kể từ ngày 10 tháng 6 năm 2014 08:00 BST, tuy nhiên có thời hạn đặt chỗ cho những khách hàng hiện tại đã có .co.uk, .org.uk, .me.uk , .net.uk, .ltd.uk hoặc tên miền .plc.uk để yêu cầu tên miền .uk tương ứng, kéo dài đến 07:59 BST vào ngày 10 tháng 6 năm 2019. " ( Nguồn )

    – Trịnh Tấn Nam 22:06:32 19/12/2018
1

Kiểm tra parse_url ()

|
1

Tôi đang thêm câu trả lời này vì đây là câu trả lời xuất hiện nhiều nhất trên Google ...

Bạn có thể sử dụng PHP để ...

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

để lấy máy chủ nhưng không phải miền riêng mà máy chủ đề cập đến. (Ví dụ www.google.co.uklà máy chủ lưu trữ, nhưng google.co.uklà miền riêng)

Để lấy tên miền riêng, bạn phải biết danh sách các hậu tố công khai mà người ta có thể đăng ký tên miền riêng. Danh sách này tình cờ được Mozilla quản lý tại https://publicsuffix.org/

Đoạn mã dưới đây hoạt động khi một mảng các hậu tố công khai đã được tạo. Chỉ cần gọi

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

với mã còn lại ...

// 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));
}
|
  • 1

    Theo thử nghiệm của tôi, parse_url cần một URL được hình thành tốt. Nếu bạn chỉ đưa ra 'www.someDomain.com/path' thì nó sẽ trả về null. Vì vậy, nó mong đợi một giao thức (như http hoặc https) sẽ có mặt.

    – Đặng Ánh Tuyết 00:28:58 15/02/2018
1

Tôi đã chỉnh sửa cho bạn:

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

Tất cả các loại url (www.domain.ltd, sub1.subn.domain.ltd sẽ dẫn đến: domain.ltd.

|
1

parse_url đã không làm việc cho tôi. Nó chỉ trở về con đường. Chuyển sang cơ bản bằng cách sử dụng php5.3 +:

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

Vui lòng xem xét thay thế giải pháp được chấp nhận bằng cách sau:

parse_url () sẽ luôn bao gồm bất kỳ tên miền phụ nào, vì vậy hàm này không phân tích tên miền rất tốt. Dưới đây là một số ví dụ:

$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

Thay vào đó, bạn có thể xem xét giải pháp thực dụng này. Nó sẽ bao gồm nhiều, nhưng không phải tất cả các tên miền - ví dụ: các tên miền cấp thấp hơn như 'sos.state.oh.us' không được bảo hiểm.

function getDomain($url) {
    $domain_array = explode(".", str_replace('www.', '', parse_url($url,PHP_URL_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

Cuối cùng, Trình phân tích miền PHP của Jeremy Kendall cho phép bạn phân tích tên miền từ một url. League URI Hostname Parser cũng sẽ thực hiện công việc.

|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.