I need to get the domain name from an URL. The following examples should all return google.com
:
google.com
images.google.com
new.images.google.com
www.google.com
Similarly the following URLs should all return google.co.uk
.
google.co.uk
images.google.co.uk
new.images.google.co.uk
http://www.google.co.uk
I'm hesitant to use Regular Expressions, because something like domain.com/google.com
could return incorrect results.
How can I get the top-level domain, using PHP? This needs to work on all platforms and hosts.
You could do this:
$urlData = parse_url($url);
$host = $urlData['host'];
** Update **
The best way I can think of is to have a mapping of all the TLDs that you want to handle, since certain TLDs can be tricky (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;
top-level domains and second-level domains may be 2 characters long but a registered subdomain must be at least 3 characters long.
EDIT: because of pjv's comment, i learned Australian domain names are an exception because they allow 5 TLDs as SLDs (com,net,org,asn,id) example: somedomain.com.au. i'm guessing com.au is nationally controlled domain name which "shares". so, technically, "com.au" would still be the "base domain", but that's not useful.
EDIT: there are 47,952 possible three-letter domain names (pattern: [a-zA-Z0-9][a-zA-Z0-9-][a-zA-Z0-9] or 36 * 37 * 36) combined with just 8 of the most common TLDS (com,org,etc) we have 383,616 possibilities -- without even adding in the entire scope of TLDs. 1-letter and 2-letter domain names still exist, but are not valid going forward.
in google.com -- "google" is a subdomain of "com"
in google.co.uk -- "google" is a subdomain of "co", which in turn is a subdomain of "uk", or a second-level domain really, since "co" is also a valid top-level domain
in www.google.com -- "www" is a subdomain of "google" which is a subdomain of "com"
"co.uk" is NOT a valid host because there is no valid domain name
going with that assumption this function will return the proper "basedomain" in almost all cases, without requiring a "url map".
if you happen to be one of the rare cases, perhaps you can modify this to fulfill particular needs...
EDIT: you must pass the domain string as a URL with it's protocol (http://, ftp://, etc) or parse_url()
will not consider it a valid URL (unless you want to modify the code to behave differently)
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 ) );
}
if you need to be accurate use fopen
or curl
to open this URL:
http://data.iana.org/TLD/tlds-alpha-by-domain.txt
then read the lines into an array and use that to compare the domain parts
EDIT: to allow for Australian domains:
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 ) );
}
IMPORTANT ADDITIONAL NOTES: I don't use this function to validate domains. It is generic code I only use to extract the base domain for the server it is running on from the global $_SERVER['SERVER_NAME']
for use within various internal scripts. Considering I have only ever worked on sites within the US, I have never encountered the Australian variants that pjv asked about. It is handy for internal use, but it is a long way from a complete domain validation process. If you are trying to use it in such a way, I recommend not to because of too many possibilities to match invalid domains.
Try using: http://php.net/manual/en/function.parse-url.php. Something like this should work:
$urlParts = parse_url($yourUrl);
$hostParts = explode('.', $urlParts['host']);
$hostParts = array_reverse($hostParts);
$host = $hostParts[1] . '.' . $hostParts[0];
Mixing with xil3 answer this is I got to check localhost as well as ip, so you can also work in development environment.
You still have to define what TLDs you want to use. other than that everything works fine.
<?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 */
}
?>
you can use it like this
$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>';
You'll get result in string like this
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With