我有一系列像这样的域名:
domain.com
second.com
www.third.com
www.fourth.fifth.com
sixth.com
seventh.eigth.com
我想要的是一个只返回主机的功能。没有子域名。
此代码是我到目前为止获取主机名的代码:
$parse = parse_url($url);
$domain = $parse['host'];
但这仅返回:
domain.com
second.com
third.com
fourth.fifth.com
sixth.com
seventh.eigth.com
我需要这个输出:
domain.com
second.com
third.com
fifth.com
sixth.com
eigth.com
答案 0 :(得分:8)
function giveHost($host_with_subdomain) {
$array = explode(".", $host_with_subdomain);
return (array_key_exists(count($array) - 2, $array) ? $array[count($array) - 2] : "").".".$array[count($array) - 1];
}
答案 1 :(得分:7)
试试此代码
<?php
/**
* @param string $domain Pass $_SERVER['SERVER_NAME'] here
* @param bool $debug
*
* @debug bool $debug
* @return string
*/
function get_domain($domain, $debug = false) {
$original = $domain = strtolower($domain);
if (filter_var($domain, FILTER_VALIDATE_IP)) { return $domain; }
$debug ? print('<strong style="color:green">»</strong> Parsing: '.$original) : false; //DEBUG
$arr = array_slice(array_filter(explode('.', $domain, 4), function($value){
return $value !== 'www'; }), 0); //rebuild array indexes
if (count($arr) > 2) {
$count = count($arr);
$_sub = explode('.', $count === 4 ? $arr[3] : $arr[2]);
$debug ? print(" (parts count: {$count})") : false; //DEBUG
if (count($_sub) === 2) { // two level TLD
$removed = array_shift($arr);
if ($count === 4) // got a subdomain acting as a domain
$removed = array_shift($arr);
$debug ? print("<br>\n" . '[*] Two level TLD: <strong>' . join('.', $_sub) . '</strong> ') : false; //DEBUG
}
elseif (count($_sub) === 1){ // one level TLD
$removed = array_shift($arr); //remove the subdomain
if (strlen($_sub[0]) === 2 && $count === 3) // TLD domain must be 2 letters
array_unshift($arr, $removed);
else{
// non country TLD according to IANA
$tlds = array( 'aero', 'arpa', 'asia', 'biz', 'cat', 'com', 'coop', 'edu', 'gov', 'info', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net', 'org', 'post', 'pro', 'tel', 'travel', 'xxx', );
if (count($arr) > 2 && in_array($_sub[0], $tlds) !== false) {//special TLD don't have a country
array_shift($arr);
}
}
$debug ? print("<br>\n" .'[*] One level TLD: <strong>'.join('.', $_sub).'</strong> ') : false; //DEBUG
}
else { // more than 3 levels, something is wrong
for ($i = count($_sub); $i > 1; $i--)
$removed = array_shift($arr);
$debug ? print("<br>\n" . '[*] Three level TLD: <strong>' . join('.', $_sub) . '</strong> ') : false; //DEBUG
}
}
elseif (count($arr) === 2) {
$arr0 = array_shift($arr);
if (strpos(join('.', $arr), '.') === false
&& in_array($arr[0], array('localhost','test','invalid')) === false) // not a reserved domain
{
$debug ? print("<br>\n" .'Seems invalid domain: <strong>'.join('.', $arr).'</strong> re-adding: <strong>'.$arr0.'</strong> ') : false; //DEBUG
// seems invalid domain, restore it
array_unshift($arr, $arr0);
}
}
$debug ? print("<br>\n".'<strong style="color:gray">«</strong> Done parsing: <span style="color:red">' . $original . '</span> as <span style="color:blue">'. join('.', $arr) ."</span><br>\n") : false; //DEBUG
return join('.', $arr);
}
//TEST
$urls = array(
'www.example.com' => 'example.com',
'example.com' => 'example.com',
'example.com.br' => 'example.com.br',
'www.example.com.br' => 'example.com.br',
'www.example.gov.br' => 'example.gov.br',
'localhost' => 'localhost',
'www.localhost' => 'localhost',
'subdomain.localhost' => 'localhost',
'www.subdomain.example.com' => 'example.com',
'subdomain.example.com' => 'example.com',
'subdomain.example.com.br' => 'example.com.br',
'www.subdomain.example.com.br' => 'example.com.br',
'www.subdomain.example.biz.br' => 'example.biz.br',
'subdomain.example.biz.br' => 'example.biz.br',
'subdomain.example.net' => 'example.net',
'www.subdomain.example.net' => 'example.net',
'www.subdomain.example.co.kr' => 'example.co.kr',
'subdomain.example.co.kr' => 'example.co.kr',
'example.co.kr' => 'example.co.kr',
'example.jobs' => 'example.jobs',
'www.example.jobs' => 'example.jobs',
'subdomain.example.jobs' => 'example.jobs',
'insane.subdomain.example.jobs' => 'example.jobs',
'insane.subdomain.example.com.br' => 'example.com.br',
'www.doubleinsane.subdomain.example.com.br' => 'example.com.br',
'www.subdomain.example.jobs' => 'example.jobs',
'test' => 'test',
'www.test' => 'test',
'subdomain.test' => 'test',
'www.detran.sp.gov.br' => 'sp.gov.br',
'www.mp.sp.gov.br' => 'sp.gov.br',
'ny.library.museum' => 'library.museum',
'www.ny.library.museum' => 'library.museum',
'ny.ny.library.museum' => 'library.museum',
'www.library.museum' => 'library.museum',
'info.abril.com.br' => 'abril.com.br',
'127.0.0.1' => '127.0.0.1',
'::1' => '::1',
);
$failed = 0;
$total = count($urls);
foreach ($urls as $from => $expected){
$from = get_domain($from, true);
if ($from !== $expected){
$failed++;
print("<div style='color:fuchsia;'>expected {$from} to be {$expected}</div>");
}
}
if ($failed)
print("{$failed} tests failed out of {$total}");
else
print("Success");
所有功劳都归pocesar
答案 2 :(得分:3)
这是适用于所有域名的域名,包括那些具有二级域名的域名,例如“co.uk”
function strip_subdomains($url){
# credits to gavingmiller for maintaining this list
$second_level_domains = file_get_contents("https://raw.githubusercontent.com/gavingmiller/second-level-domains/master/SLDs.csv");
# presume sld first ...
$possible_sld = implode('.', array_slice(explode('.', $url), -2));
# and then verify it
if (strpos($second_level_domains, $possible_sld)){
return implode('.', array_slice(explode('.', $url), -3));
} else {
return implode('.', array_slice(explode('.', $url), -2));
}
}
答案 3 :(得分:2)
我更喜欢使用正则表达式来做这件事,对我来说更容易理解:
$url = "http://www.domain.com";
$parse = parse_url($url);
echo preg_replace("/^([a-zA-Z0-9].*\.)?([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z.]{2,})$/", '$2', $parse['host']);
答案 4 :(得分:1)
尝试使用str_replace();
$parse = parse_url($url);
$domain = str_replace('www.','',$parse['host']);
答案 5 :(得分:1)
我正在使用Baptiste Donaux的版本,直到需要检查“localhost&#39;”。我认为Shanoop的版本更可靠。
我已经在190个断言的测试套件中测试了这两个版本,并且对性能没有太大影响。如果仍有问题,您可以使用Redis或类似方法将结果缓存到生产中。
这是Shanoop的答案版本,但是没有调试行和一点清理:
function stripSubdomain($domain)
{
$domain = strtolower($domain);
if (isIp($domain)) ? return $domain;
return stripArray( buildArray($domain) );
}
function isIp($domain)
{
return (filter_var($domain, FILTER_VALIDATE_IP));
}
function buildArray($domain)
{
return array_slice(array_filter(explode('.', $domain, 4), function($value){
return $value !== 'www';
}), 0);
}
function stripArray($arr)
{
// TLD Domains
if (count($arr) > 2) {
$count = count($arr);
$_sub = $this->retrieveSubdomain($arr);
// two level TLD
if (count($_sub) === 2) {
array_shift($arr);
if ($count === 4) array_shift($arr);
}
// one level TLD
elseif (count($_sub) === 1){
$removed = array_shift($arr);
if (strlen($_sub[0]) === 2 && $count === 3) array_unshift($arr, $removed);
else {
// non country TLD according to IANA
$tlds = ['aero', 'arpa', 'asia', 'biz', 'cat', 'com', 'coop',
'edu', 'gov', 'info', 'jobs', 'mil', 'mobi', 'museum',
'name', 'net', 'org', 'post', 'pro', 'tel', 'travel', 'xxx'];
if (count($arr) > 2 &&
in_array($_sub[0], $tlds) !== false) array_shift($arr);
}
}
// more than 3 levels, something is wrong
else
for ($i = count($_sub); $i > 1; $i--) array_shift($arr);
}
// Special Domains
elseif (count($arr) === 2) {
$removed = array_shift($arr);
$reserved = ['localhost','test','invalid'];
if (strpos(join('.', $arr), '.') === false && in_array($arr[0], $reserved) === false)
array_unshift($arr, $removed); // seems invalid domain, restore it
}
return join('.', $arr);
}
function retrieveSubdomain($arr)
{
return explode('.', (count($arr) === 4 ? $arr[3] : $arr[2]) );
}
答案 6 :(得分:0)
这个适用于大多数域名,如果我必须自己这样说,那就很优雅!
public static function StripSubdomain($Domain) {
$domain_array = explode('.', $Domain);
$domain_array = array_reverse($domain_array);
return $domain_array[1] . '.' . $domain_array[0];
}
答案 7 :(得分:0)
尝试一下。我喜欢这种简单性,并且它在大多数用例中都对我有用。
$domains = [
"domain.com",
"second.com",
"www.third.com",
"www.fourth.fifth.com",
"openhours.colyn.dev"
];
$domains = array_map(function ($domain) {
$parts = explode('.', $domain);
return implode('.', array_slice($parts, count($parts)-2));
}, $domains);
/**
[
"domain.com",
"second.com",
"third.com",
"fifth.com",
"colyn.dev",
]
*/
不是超级健壮,但对我来说,它工作正常。