2010-07-09 39 views
13

Tôi cần lấy tên miền từ một URL. Các ví dụ sau đây tất cả sẽ trả lại google.com:Làm thế nào để lấy tên miền cơ sở từ một URL bằng cách sử dụng PHP?

google.com 
images.google.com 
new.images.google.com 
www.google.com 

Tương tự, tất cả các URL sau đều phải trả về google.co.uk.

google.co.uk 
images.google.co.uk 
new.images.google.co.uk 
http://www.google.co.uk 

Tôi do dự khi sử dụng Cụm từ thông dụng, vì một cái gì đó như domain.com/google.com có thể trả lại kết quả không chính xác.

Làm cách nào để có được miền cấp cao nhất, sử dụng PHP? Điều này cần phải hoạt động trên tất cả các nền tảng và máy chủ.

+1

Đây là khéo léo. Đối với 'google.com', bạn quan tâm đến TLD và tên miền cấp hai. Đối với 'google.co.uk', bạn muốn TLD và tên miền cấp 2 và cấp 3. Không có "tên cơ sở" được xác định, ý nghĩa của "tên cơ sở" là khác nhau đối với các nhà đăng ký/TLD khác nhau. – deceze

+1

Tôi khá chắc chắn bạn phải có một chút dài quanh co ở đây, những gì bạn đang yêu cầu là ăn bánh của bạn và có nó quá. Nếu không có danh sách TLD thì không có cách nào để phân biệt giữa co.uk và google.com, chúng đều là tên máy chủ. –

+0

Tôi đoán các bạn nói đúng, có vẻ như mọi thứ sẽ không hoạt động nếu không có nhiều mã – Rohan

Trả lời

16

Bạn có thể làm điều này:

$urlData = parse_url($url); 

$host = $urlData['host']; 

** Update **

Cách tốt nhất tôi có thể nghĩ đến là phải có một bản đồ của tất cả các tên miền cấp cao mà bạn muốn xử lý, vì một số TLD nhất định có thể phức tạp (co.uk).

// you can add more to it if you want 
$urlMap = array('com', 'co.uk'); 

$host = ""; 
$url = "http://www.google.co.uk"; 

$urlData = parse_url($url); 
$hostData = explode('.', $urlData['host']); 
$hostData = array_reverse($hostData); 

if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) { 
    $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0]; 
} elseif(array_search($hostData[0], $urlMap) !== FALSE) { 
    $host = $hostData[1] . '.' . $hostData[0]; 
} 

echo $host; 
3

Thử sử dụng: http://php.net/manual/en/function.parse-url.php. Một cái gì đó như thế này nên làm việc:

$urlParts = parse_url($yourUrl); 
$hostParts = explode('.', $urlParts['host']); 
$hostParts = array_reverse($hostParts); 
$host = $hostParts[1] . '.' . $hostParts[0]; 
+1

Điều đó sẽ vi phạm nếu bạn có một cái gì đó như thế này: http: //www.google.co.uk - trong trường hợp đó, nó sẽ trả về "co.uk". – xil3

+1

Nó thực sự, cách duy nhất để có được sắp xếp mặc dù là bằng cách sử dụng một danh sách TLD. –

-3

Sử dụng chức năng này:

function getHost($url){ 
    if (strpos($url,"http://")){ 
     $httpurl=$url; 
    } else { 
     $httpurl="http://".$url; 
    } 
    $parse = parse_url($httpurl); 
    $domain=$parse['host']; 

    $portion=explode(".",$domain); 
    $count=sizeof($portion)-1; 
    if ($count>1){ 
     $result=$portion[$count-1].".".$portion[$count]; 
    } else { 
     $result=$domain; 
    } 
    return $result; 
} 

trả lời tất cả các biến thể của ví dụ URL.

5

tên miền cấp cao nhất và tên miền cấp 2 có thể dài 2 ký tự nhưng tên miền phụ đã đăng ký phải dài ít nhất 3 ký tự.

EDIT: vì nhận xét của pjv, tôi đã học được tên miền của Úc là ngoại lệ vì chúng cho phép 5 TLD làm SLD (com, net, org, asn, id) ví dụ: somedomain.com.au. Tôi đoán com.au là tên miền được kiểm soát trên toàn quốc mà "cổ phiếu". vì vậy, về mặt kỹ thuật, "com.au" vẫn sẽ là "tên miền cơ sở", nhưng điều đó không hữu ích.

CHỈNH SỬA: có 47.952 tên miền có ba chữ cái (mẫu: [a-zA-Z0-9] [a-zA-Z0-9 -] [a-zA-Z0-9] hoặc 36 * 37 * 36) kết hợp với chỉ 8 của TLDS phổ biến nhất (com, org, vv), chúng tôi có 383,616 khả năng - thậm chí không thêm vào toàn bộ phạm vi của TLD. Tên miền 1 ký tự và 2 ký tự vẫn tồn tại, nhưng không hợp lệ trong tương lai.

trong google.com - "google" là một tên miền phụ của "com"

trong google.co.uk - "google" là một tên miền phụ của "đồng", mà lần lượt là tên miền phụ của "uk" hoặc tên miền cấp hai thực sự, vì "co" cũng là tên miền cấp cao hợp lệ

trong www.google.com - "www" là tên miền phụ của "google" là tên miền phụ của "com"

"co.uk" không phải là máy chủ lưu trữ hợp lệ vì không có tên miền hợp lệ

đi với giả định đó ion chức năng này sẽ trả lại "tên miền phụ" thích hợp trong hầu hết các trường hợp, mà không yêu cầu "bản đồ url".

nếu bạn là một trong những trường hợp hiếm hoi, có lẽ bạn có thể sửa đổi điều này để đáp ứng các nhu cầu cụ thể ...

EDIT: bạn phải chuyển chuỗi miền dưới dạng URL với giao thức của nó (http: //, ftp: //, v.v.) hoặc parse_url() sẽ không coi đó là URL hợp lệ (trừ khi bạn muốn sửa đổi mã để hoạt động khác nhau)

function basedomain($str = '') 
{ 
    // $str must be passed WITH protocol. ex: http://domain.com 
    $url = @parse_url($str); 
    if (empty($url['host'])) return; 
    $parts = explode('.', $url['host']); 
    $slice = (strlen(reset(array_slice($parts, -2, 1))) == 2) && (count($parts) > 2) ? 3 : 2; 
    return implode('.', array_slice($parts, (0 - $slice), $slice)); 
} 

nếu bạn cần phải chính xác sử dụng fopen hoặc curl để mở URL này: http://data.iana.org/TLD/tlds-alpha-by-domain.txt

sau đó đọc các dòng vào một mảng và sử dụng để so sánh các phần miền

.210

EDIT: để cho phép cho các tên miền Úc:

function au_basedomain($str = '') 
{ 
    // $str must be passed WITH protocol. ex: http://domain.com 
    $url = @parse_url($str); 
    if (empty($url['host'])) return; 
    $parts = explode('.', $url['host']); 
    $slice = (strlen(reset(array_slice($parts, -2, 1))) == 2) && (count($parts) > 2) ? 3 : 2; 
    if (preg_match('/\.(com|net|asn|org|id)\.au$/i', $url['host'])) $slice = 3; 
    return implode('.', array_slice($parts, (0 - $slice), $slice)); 
} 

QUAN TRỌNG Ghi chú thêm: Tôi không sử dụng chức năng này để xác nhận lĩnh vực. Đó là mã chung mà tôi chỉ sử dụng để trích xuất miền cơ sở cho máy chủ mà nó đang chạy từ toàn cầu $_SERVER['SERVER_NAME'] để sử dụng trong các tập lệnh nội bộ khác nhau. Xem xét tôi đã từng làm việc trên các trang web trong nước Mỹ, tôi chưa bao giờ gặp phải các biến thể của Úc mà pjv hỏi. Nó rất tiện lợi cho việc sử dụng nội bộ, nhưng nó là một chặng đường dài từ một quá trình xác nhận tên miền hoàn chỉnh. Nếu bạn đang cố gắng sử dụng nó theo cách như vậy, tôi khuyên bạn không nên vì quá nhiều khả năng để phù hợp với tên miền không hợp lệ.

+1

Nếu bạn thay đổi 'strlen() == 2' thành' <= 3', bạn sẽ bắt được 99% các tên miền, lưu các tên miền phụ trên localhost và không có gì. Đây là bản sửa đổi của tôi được dọn dẹp: https://gist.github.com/anonymous/fe77c97e632675411c3c – Mahn

+0

Không, bản sửa đổi không hoạt động chính xác. Nó cần phải được == 2 vì <= 3 sẽ khớp với khi phần tiếp theo của phần cuối cùng là 3 - mà chúng ta không muốn làm. Chúng tôi muốn nó trả về "google.com" từ "www.google.com" hoặc "mail.google.com" và chúng tôi muốn nó trả về "google.co.uk" từ "www.google.co.uk" hoặc "mail.google.co.uk" – aequalsb

+0

@Mahn Ngoài ra, có nhiều bit bổ sung trong bản sửa đổi của bạn - các bài tập biến không cần thiết và điều kiện làm tổ không cần thiết. Mã khác và kết quả không mong muốn - bạn có kiểm tra kỹ lưỡng bản sửa đổi của mình không? – aequalsb

0

Trộn với câu trả lời xil3 đây là tôi phải kiểm tra localhost cũng như ip, vì vậy bạn cũng có thể làm việc trong môi trường phát triển.
Bạn vẫn phải xác định những TLD nào bạn muốn sử dụng. khác hơn là tất cả mọi thứ hoạt động tốt.

<?php 
function getTopLevelDomain($url){ 
    $urlData = parse_url($url); 
    $urlHost = isset($urlData['host']) ? $urlData['host'] : ''; 
    $isIP = (bool)ip2long($urlHost); 
    if($isIP){ /** To check if it's ip then return same ip */ 
     return $urlHost; 
    } 
    /** Add/Edit you TLDs here */ 
    $urlMap = array('com', 'com.pk', 'co.uk'); 

    $host = ""; 
    $hostData = explode('.', $urlHost); 
    if(isset($hostData[1])){ /** To check "localhost" because it'll be without any TLDs */ 
     $hostData = array_reverse($hostData); 

     if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) { 
      $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0]; 
     } elseif(array_search($hostData[0], $urlMap) !== FALSE) { 
      $host = $hostData[1] . '.' . $hostData[0]; 
     } 
     return $host; 
    } 
    return ((isset($hostData[0]) && $hostData[0] != '') ? $hostData[0] : 'error no domain'); /* You can change this error in future */ 
} 
?> 

bạn có thể sử dụng nó như thế này

$string = 'http://googl.com.pk'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com.pk:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com.pk'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com.pk:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://192.168.0.101:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://192.168.0.101'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://localhost'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'https;//'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = ''; 
echo getTopLevelDomain($string) . '<br>'; 

Bạn sẽ nhận được kết quả trong chuỗi như thế này

googl.com.pk 
googl.com.pk 
googl.com 
googl.com 
googl.com.pk 
googl.com.pk 
googl.com 
googl.com 
192.168.0.101 
192.168.0.101 
localhost 
error no domain 
error no domain 
Các vấn đề liên quan