Удалить субдомен из строки url, если найден субдомен

У меня есть массив таких доменов:

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 

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

Попробуйте этот код

  <?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">&raquo;</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">&laquo;</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

Я использовал версию Baptiste Donaux до тех пор, пока не понадобятся для проверки «localhost». Я думаю, что версия Shanoop более надежна.

Я тестировал обе версии в testuite с 190 утверждениями и не оказывает большого влияния на производительность. Если все еще milisseconds вызывает беспокойство, вы можете просто кэшировать результаты в производстве с помощью 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]) ); } 

Попробуйте с str_replace ();

 $parse = parse_url($url); $domain = str_replace('www.','',$parse['host']); 

Я предпочитаю использовать regex для этого, это легче понять для меня:

 $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']); 

Это хорошо работает для большинства доменов, и элегантно, если я должен сказать это сам!

 public static function StripSubdomain($Domain) { $domain_array = explode('.', $Domain); $domain_array = array_reverse($domain_array); return $domain_array[1] . '.' . $domain_array[0]; } 

Вот один из них, который работает для всех доменов, в том числе для доменов второго уровня, таких как «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)); } }