2008-12-30 12 views
12

Parse_url() của PHP có trường máy chủ lưu trữ, bao gồm máy chủ lưu trữ đầy đủ. Tôi đang tìm cách đáng tin cậy nhất (và ít tốn kém nhất) để chỉ trả về miền và TLD.Đi nơi PHP parse_url() không - Chỉ phân tích cú pháp miền

Với ví dụ:

Tôi chỉ tìm kiếm google.com hoặc google.co.uk. Tôi đã dự tính một bảng TLD/hậu tố hợp lệ và chỉ cho phép những người đó và một từ. Bạn sẽ làm điều đó theo bất kỳ cách nào khác? Có ai biết về một REGEX hợp lệ đóng trước cho loại điều này?

+0

Bạn đã đánh giá trước rằng tôi không chắc chắn sẽ giữ đủ tốt, đó là bạn có thể biết phần nào của máy chủ là tên miền mà bạn quan tâm thực sự là TLD? –

+0

Ví dụ, chỉ cần về bất kỳ tên miền dyndns dường như bị chặn nếu bạn chỉ nhìn vào tên miền chuẩn. Để ngăn chặn thư rác từ tên miền của www.mysite.isa-geek.org, hoặc chỉ mysite.isa-geek.org bạn sẽ quan tâm nếu bạn đã chặn tất cả isa-geek.org? –

+0

Có, tôi sẽ bị chặn là isa-geek.org trong trường hợp này. Tôi quan tâm nhất đến foo. [Hậu tố] trong đó [hậu tố] là tld hoặc combo của hậu tố chuẩn. tld (co.uk) –

Trả lời

17

Làm thế nào về điều gì đó như vậy?

function getDomain($url) { 
    $pieces = parse_url($url); 
    $domain = isset($pieces['host']) ? $pieces['host'] : ''; 
    if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) { 
    return $regs['domain']; 
    } 
    return false; 
} 

sẽ trích xuất các tên miền bằng cách sử dụng cổ điển parse_url và sau đó tìm kiếm một tên miền hợp lệ mà không cần bất kỳ tên miền phụ (www là tên miền phụ). Sẽ không làm việc trên những thứ như 'localhost'. Sẽ trả về false nếu nó không khớp với bất kỳ thứ gì.

// Edit:

Hãy thử nó với:

echo getDomain('http://www.google.com/test.html') . '<br/>'; 
echo getDomain('https://news.google.co.uk/?id=12345') . '<br/>'; 
echo getDomain('http://my.subdomain.google.com/directory1/page.php?id=abc') . '<br/>'; 
echo getDomain('https://testing.multiple.subdomain.google.co.uk/') . '<br/>'; 
echo getDomain('http://nothingelsethan.com') . '<br/>'; 

Và nó sẽ trả về:

google.com 
google.co.uk 
google.com 
google.co.uk 
nothingelsethan.com 

Tất nhiên, nó sẽ không trở lại bất cứ điều gì nếu nó doesn Không vượt qua được parse_url, vì vậy hãy đảm bảo đó là URL được tạo đúng.

// Phụ Lục:

Alnitak là đúng.Giải pháp được trình bày ở trên sẽ hoạt động trong hầu hết các trường hợp nhưng không nhất thiết phải tất cả và cần được duy trì để đảm bảo, ví dụ: TLD mới của chúng không có .morethan6characters.vv. Cách đáng tin cậy duy nhất để giải nén miền là sử dụng danh sách được duy trì như http://publicsuffix.org/. Ban đầu nó đau đớn hơn nhưng dễ dàng hơn và mạnh mẽ hơn về lâu dài. Bạn cần phải chắc chắn rằng bạn hiểu được ưu và nhược điểm của từng phương pháp và cách nó phù hợp với dự án của bạn.

+0

Bất kỳ lý do gì khiến ai đó bỏ phiếu bầu chọn này? Chúng tôi có thể cố gắng cải thiện câu trả lời nếu nó không đúng hoặc nếu có gì đó được thêm vào. – lpfavreau

+2

Tôi đã bỏ phiếu này - đây không phải là câu trả lời đúng. Không thể dứt khoát tìm ra "phần tên miền" (tức là bỏ qua "www", v.v.) chỉ với một cụm từ đơn giản. Xem các câu hỏi liên quan và câu trả lời của họ được liên kết ở nơi khác. Danh sách publicsuffix.org là phương pháp đáng tin cậy nhất. – Alnitak

+0

Tôi không hiểu tại sao công trình này lại hoạt động. Ngoài ra, nó phải là '[a-z0-9] [a-z0-9 \ -] {1,62}', phải không? –

1

Dug này lên từ một bài liên quan, cho ý tưởng của việc giữ một bảng: http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/src/effective_tld_names.dat?raw=1

Tôi không muốn làm điều đó mặc dù.

+0

Tôi sợ sử dụng danh sách đó là cách duy nhất. có quá nhiều loại ccTLD để viết giải pháp sẽ làm tất cả. –

+0

Liên kết không hoạt động nữa :(Đã có liên kết này trong danh sách liên kết của tôi ... – powtac

0

Tất nhiên nó phụ thuộc vào trường hợp sử dụng cụ thể của bạn, nhưng nói chung tôi sẽ không sử dụng tra cứu bảng cho TLD. Các TLD mới xuất hiện và bạn thường không muốn duy trì chúng ở bất cứ đâu. Chỉ cần hỏi tôi làm thế nào thường [email protected] của tôi đã bị từ chối vì shortightedness.

Tôi đoán tôi có thể giúp đỡ tốt hơn nếu tôi biết lý do bạn không muốn www? Bạn có cần nó cho email không? Bạn có thể truy vấn bản ghi MX trong các trường hợp như vậy để xác minh nó (cuối cùng) chấp nhận thư.

Bạn cũng có thể tìm trợ giúp với các hàm PHP xử lý bản ghi DNS để tìm hiểu thêm thông tin về chúng, xem ví dụ http://php.net/dns_get_record.

+0

Tôi đang tìm cách sử dụng liên kết này làm danh sách đen của các tên miền spammer và ngăn mọi người sử dụng DNS ký tự đại diện để khám phá nó. hoặc nhận xét spam hơn email –

0

Chỉ là bằng chứng, giả sử các trường được phép được ghi nhớ thành một băm. Mã có thể được rút ngắn rất nhiều.

<?php 
    $urlCompoments=parse_url($theUrl); 
    $chunk=explode('.',$urlComponents['host']); 

    $tldIndex = count($chunk-1); // assume last chunk is tld 
    $maxTldLen = 2; // assuming a tld can be in the form .com or .co.uk 
    $cursor=1; 
    $found=false; 
    while(($cursor<=$maxTldLen) or $found) { 
     $tls = implode('.',array_slice($chunk, -$cursor)); 
     $found=isset($tldSuffixesAllowed[$tld]); 
     $cursor++; 
    } 
    if ($found){ 
     $tld=implode('.',array_slice($chunk, -$cursor)); 
    } else { 
     // domain not recognized, do wathever you want 
    } 
?> 
6

Hiện nay chỉ cách "đúng" để làm điều này là sử dụng một danh sách như rằng duy trì ở mức http://publicsuffix.org/

BTW, câu hỏi này cũng là khá nhiều bản sao của:

Có những nỗ lực chuẩn hóa tại IETF xem phương pháp khai báo DNS cho dù một nút cụ thể trong cây DNS được sử dụng cho đăng ký "công khai", nhưng chúng đang ở giai đoạn phát triển ban đầu. Tất cả các trình duyệt không phải là trình duyệt IE phổ biến đều sử dụng danh sách publicsuffix.org.

-2

Có một giải pháp thực sự dễ dàng như thế này:

function get_domain($url) { 
    $pieces = parse_url($url); 
    return array_pop(explode('.', $pieces['host'], 2)); 
} 

Chắc chắn điều này sẽ làm việc?

3

Ngoài ra còn có một cổng rất đẹp của mô-đun tldextract của Python http://w-shadow.com/blog/2012/08/28/tldextract - điều này vượt quá parse_url và cho phép bạn thực sự có được miền/tld ra, mà không có tên miền phụ.

Từ trang web của mô-đun:

$components = tldextract('http://www.bbc.co.uk'); 
echo $components->subdomain; // www 
echo $components->domain; // bbc 
echo $components->tld;  // co.uk 
0

Bạn cần gói có sử dụng Public Suffix List, chỉ bằng cách này bạn có thể trích xuất một cách chính xác lĩnh vực với TLD hai, cấp ba (co.uk, a.bg, b .bg, v.v.) và các tên miền phụ đa cấp. Hàm Regex, parse_url() hoặc chuỗi sẽ không bao giờ tạo ra kết quả hoàn toàn chính xác.

Tôi khuyên bạn nên sử dụng TLD Extract. Dưới đây là ví dụ về mã:

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

$result = $extract->parse('http://www.google.co.uk/foo'); 
$result->getSubdomain(); // will return (string) 'www' 
$result->getHostname(); // will return (string) 'google' 
$result->getSuffix(); // will return (string) 'co.uk' 
$result->getRegistrableDomain(); // will return (string) 'google.co.uk' 
Các vấn đề liên quan