Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP code to get the domain name without subdomains (includes the tld, and the special types from IANA). Don't have support for unicode domain names.
<?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;
$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;
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;
}
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;
}
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;
}
}
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;
// 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;
return join('.', $arr);
}
$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

This comment has been minimized.

Copy link
Owner Author

pocesar commented Apr 11, 2013

Codepad code running http://codepad.viper-7.com/GAh1tP

@domyen

This comment has been minimized.

Copy link

domyen commented Dec 26, 2013

Thank you!

@laimisf

This comment has been minimized.

Copy link

laimisf commented Mar 28, 2014

Thank You! This code helped me a lot ;)

@0xibram

This comment has been minimized.

Copy link

0xibram commented Dec 27, 2014

Thanks!

@neo22s

This comment has been minimized.

Copy link

neo22s commented Feb 18, 2015

Doesn't work for domains with TLD of len = 2:

'dev.example.ca' => 'example.ca',
'dev.example.io' => 'example.io',

Example:
http://codepad.viper-7.com/AB1Hg6

@Titogelo

This comment has been minimized.

Copy link

Titogelo commented May 20, 2015

Nice job. Thanks a lot man! :)

@NabiKAZ

This comment has been minimized.

Copy link

NabiKAZ commented Jun 2, 2016

does not work for sub.example.co and return sub.example.co

@pocesar

This comment has been minimized.

Copy link
Owner Author

pocesar commented Aug 8, 2016

the best thing is to create a lookup array with all available TLDs from IANA, a lot have been added since 2013 including having support for punycode https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains a bit of manual setup at first, but performance, and strictly compliant to the list

@codeMonkeyK

This comment has been minimized.

Copy link

codeMonkeyK commented Mar 8, 2017

very cool! Saves some custom code writting! Thanks!

@gopalkumar315

This comment has been minimized.

Copy link

gopalkumar315 commented Apr 9, 2018

Well written code for finding main domain, thanks...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.