PHP function to get the subdomain of a URL

PhpSubdomain

Php Problem Overview


Is there a function in PHP to get the name of the subdomain?

In the following example I would like to get the "en" part of the URL:

en.example.com

Php Solutions


Solution 1 - Php

Here's a one line solution:

array_shift((explode('.', $_SERVER['HTTP_HOST'])));

Or using your example:

array_shift((explode('.', 'en.example.com')));

EDIT: Fixed "only variables should be passed by reference" by adding double parenthesis.


EDIT 2: Starting from PHP 5.4 you can simply do:

explode('.', 'en.example.com')[0];

Solution 2 - Php

Uses the parse_url function.

$url = 'http://en.example.com';

$parsedUrl = parse_url($url);

$host = explode('.', $parsedUrl['host']);

$subdomain = $host[0];
echo $subdomain;

For multiple subdomains

$url = 'http://usa.en.example.com';

$parsedUrl = parse_url($url);

$host = explode('.', $parsedUrl['host']);

$subdomains = array_slice($host, 0, count($host) - 2 );
print_r($subdomains);

Solution 3 - Php

You can do this by first getting the domain name (e.g. sub.example.com => example.co.uk) and then use strstr to get the subdomains.

$testArray = array(
	'sub1.sub2.example.co.uk',
	'sub1.example.com',
	'example.com',
	'sub1.sub2.sub3.example.co.uk',
	'sub1.sub2.sub3.example.com',
	'sub1.sub2.example.com'
);

foreach($testArray as $k => $v)
{
	echo $k." => ".extract_subdomains($v)."\n";
}

function extract_domain($domain)
{
	if(preg_match("/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i", $domain, $matches))
    {
        return $matches['domain'];
    } else {
        return $domain;
    }
}

function extract_subdomains($domain)
{
	$subdomains = $domain;
    $domain = extract_domain($subdomains);
    
    $subdomains = rtrim(strstr($subdomains, $domain, true), '.');

    return $subdomains;
}

Outputs:

0 => sub1.sub2
1 => sub1
2 =>
3 => sub1.sub2.sub3
4 => sub1.sub2.sub3
5 => sub1.sub2

Solution 4 - Php

http://php.net/parse_url

<?php
  $url = 'http://user:[email protected]/path?argument=value#anchor';
  $array=parse_url($url);
  $array['host']=explode('.', $array['host']);

  echo $array['host'][0]; // returns 'sub'
?>

Solution 5 - Php

As the only reliable source for domain suffixes are the domain registrars, you can't find the subdomain without their knowledge. There is a list with all domain suffixes at https://publicsuffix.org. This site also links to a PHP library: https://github.com/jeremykendall/php-domain-parser.

Please find an example below. I also added the sample for en.test.co.uk which is a domain with a multi suffix (co.uk).

<?php

require_once 'vendor/autoload.php';

$pslManager = new Pdp\PublicSuffixListManager();
$parser = new Pdp\Parser($pslManager->getList());
$host = 'http://en.example.com';
$url = $parser->parseUrl($host);

echo $url->host->subdomain;


$host = 'http://en.test.co.uk';
$url = $parser->parseUrl($host);

echo $url->host->subdomain;

Solution 6 - Php

Simply...

    preg_match('/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i', $url, $match);

Just read $match[1]

Working example

It works perfectly with this list of urls

$url = array(
    'http://www.domain.com', // www
    'http://domain.com', // --nothing--
    'https://domain.com', // --nothing--
    'www.domain.com', // www
    'domain.com', // --nothing--
    'www.domain.com/some/path', // www
    'http://sub.domain.com/domain.com', // sub
    'опубликованному.значения.ua', // опубликованному ;)
    'значения.ua', // --nothing--
    'http://sub-domain.domain.net/domain.net', // sub-domain
    'sub-domain.third-Level_DomaIN.domain.uk.co/domain.net' // sub-domain
);

foreach ($url as $u) {
    preg_match('/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i', $u, $match);
    var_dump($match);
}

Solution 7 - Php

Simplest and fastest solution.

$sSubDomain = str_replace('.example.com','',$_SERVER['HTTP_HOST']);

Solution 8 - Php

PHP 7.0: Use the explode function and create a list of all the results.

list($subdomain,$host) = explode('.', $_SERVER["SERVER_NAME"]);

Example: sub.domain.com

echo $subdomain; 

Result: sub

echo $host;

Result: domain

Solution 9 - Php

$REFERRER = $_SERVER['HTTP_REFERER']; // Or other method to get a URL for decomposition

$domain = substr($REFERRER, strpos($REFERRER, '://')+3);
$domain = substr($domain, 0, strpos($domain, '/'));
// This line will return 'en' of 'en.example.com'
$subdomain = substr($domain, 0, strpos($domain, '.')); 

Solution 10 - Php

Using regex, string functions, parse_url() or their combinations it's not real solution. Just test any of proposed solutions with domain test.en.example.co.uk, there will no any correct result.

Correct solution is use package that parses domain with Public Suffix List. I recomend TLDExtract, here is sample code:

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

$result = $extract->parse('test.en.example.co.uk');
$result->getSubdomain(); // will return (string) 'test.en'
$result->getSubdomains(); // will return (array) ['test', 'en']
$result->getHostname(); // will return (string) 'example'
$result->getSuffix(); // will return (string) 'co.uk'

Solution 11 - Php

What I found the best and short solution is

array_shift(explode(".",$_SERVER['HTTP_HOST']));

Solution 12 - Php

For those who get 'Error: Strict Standards: Only variables should be passed by reference.' Use like this:

$env = (explode(".",$_SERVER['HTTP_HOST'])); $env = array_shift($env);

Solution 13 - Php

$domain = 'sub.dev.example.com';
$tmp = explode('.', $domain); // split into parts
$subdomain = current($tmp);
print($subdomain);     // prints "sub"

As seen in a previous question: https://stackoverflow.com/questions/13832626/how-to-get-the-first-subdomain-with-php

Solution 14 - Php

There isn't really a 100% dynamic solution - I've just been trying to figure it out as well and due to different domain extensions (DTL) this task would be really difficult without actually parsing all these extensions and checking them each time:

The most reliable option is to define a constant (or database entry etc.) that stores the actual domain name and remove it from the $_SERVER['SERVER_NAME'] using substr()

defined("DOMAIN")
    || define("DOMAIN", 'mymaindomain.co.uk');
    
    

function getSubDomain() {

	if (empty($_SERVER['SERVER_NAME'])) {

        return null;

    }

    $subDomain = substr($_SERVER['SERVER_NAME'], 0, -(strlen(DOMAIN)));

    if (empty($subDomain)) {
	    
	    return null;

    }
    
    return rtrim($subDomain, '.');

}

Now if you're using this function under http://test.mymaindomain.co.uk it will give you test or if you have multiple sub-domain levels http://another.test.mymaindomain.co.uk you'll get another.test - unless of course you update the DOMAIN.

I hope this helps.

Solution 15 - Php

Simply

reset(explode(".", $_SERVER['HTTP_HOST']))

Solution 16 - Php

this is my solution, it works with the most common domains, you can fit the array of extensions as you need:

$SubDomain = explode('.', explode('|ext|', str_replace(array('.com', '.net', '.org'), '|ext|',$_SERVER['HTTP_HOST']))[0]);

Solution 17 - Php

I'm doing something like this

$url = https://en.example.com

$splitedBySlash = explode('/', $url);
$splitedByDot = explode('.', $splitedBySlash[2]);
   
$subdomain = $splitedByDot[0];

Solution 18 - Php

Suppose current url = sub.example.com

$host = array_reverse(explode('.', $_SERVER['SERVER_NAME']));
 
if (count($host) >= 3){
   echo "Main domain is = ".$host[1].".".$host[0]." & subdomain is = ".$host[2];
   // Main domain is = example.com & subdomain is = sub
} else {
   echo "Main domain is = ".$host[1].".".$host[0]." & subdomain not found";
   // "Main domain is = example.com & subdomain not found";
}

Solution 19 - Php

// For www.abc.en.example.com 
$host_Array = explode(".",$_SERVER['HTTP_HOST']); // Get HOST as array www, abc, en, example, com
array_pop($host_Array); array_pop($host_Array);   // Remove com and exmaple
array_shift($host_Array);                         // Remove www (Optional)
echo implode($host_Array, ".");                   // Combine array abc.en

Solution 20 - Php

I know I'm really late to the game, but here goes.

What I did was take the HTTP_HOST server variable ($_SERVER['HTTP_HOST']) and the number of letters in the domain (so for example.com it would be 11).

Then I used the substr function to get the subdomain. I did

$numberOfLettersInSubdomain = strlen($_SERVER['HTTP_HOST'])-12
$subdomain = substr($_SERVER['HTTP_HOST'], $numberOfLettersInSubdomain);

I cut the substring off at 12 instead of 11 because substrings start on 1 for the second parameter. So now if you entered test.example.com, the value of $subdomain would be test.

This is better than using explode because if the subdomain has a . in it, this will not cut it off.

Solution 21 - Php

if you are using drupal 7

this will help you:

global $base_path;
global $base_root;	
$fulldomain = parse_url($base_root);	
$splitdomain = explode(".", $fulldomain['host']);
$subdomain = $splitdomain[0];

Solution 22 - Php

$host = $_SERVER['HTTP_HOST'];
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
$domain = $matches[0];
$url = explode($domain, $host);
$subdomain = str_replace('.', '', $url[0]);

echo 'subdomain: '.$subdomain.'<br />';
echo 'domain: '.$domain.'<br />';

Solution 23 - Php

From PHP 5.3 you can use strstr() with true parameter

echo strstr($_SERVER["HTTP_HOST"], '.', true); //prints en

Solution 24 - Php

function get_subdomain($url=""){
	if($url==""){
		$url = $_SERVER['HTTP_HOST'];
	}
	$parsedUrl = parse_url($url);
	$host = explode('.', $parsedUrl['path']);
	$subdomains = array_slice($host, 0, count($host) - 2 );
	return implode(".", $subdomains);
}

Solution 25 - Php

Try this...

$domain = 'en.example.com';
$tmp = explode('.', $domain);
$subdomain = current($tmp);
echo($subdomain);     // echo "en"

Solution 26 - Php

you can use this too

echo substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.', -5));

Solution 27 - Php

We use this function to handle multiple subdomain and multiple tld also handle ip and localhost

function analyse_host($_host)
	{
		$my_host   = explode('.', $_host);
		$my_result = ['subdomain' => null, 'root' => null, 'tld' => null];

		// if host is ip, only set as root
		if(filter_var($_host, FILTER_VALIDATE_IP))
		{
			// something like 127.0.0.5
			$my_result['root'] = $_host;
		}
		elseif(count($my_host) === 1)
		{
			// something like localhost
			$my_result['root'] = $_host;
		}
		elseif(count($my_host) === 2)
		{
			// like jibres.com
			$my_result['root'] = $my_host[0];
			$my_result['tld']  = $my_host[1];
		}
		elseif(count($my_host) >= 3)
		{
			// some conditons like
			// ermile.ac.ir
			// ermile.jibres.com
			// ermile.jibres.ac.ir
			// a.ermile.jibres.ac.ir

			// get last one as tld
			$my_result['tld']  = end($my_host);
			array_pop($my_host);

			// check last one after remove is probably tld or not
			$known_tld    = ['com', 'org', 'net', 'gov', 'co', 'ac', 'id', 'sch', 'biz'];
			$probably_tld = end($my_host);
			if(in_array($probably_tld, $known_tld))
			{
				$my_result['tld'] = $probably_tld. '.'. $my_result['tld'];
				array_pop($my_host);
			}

			$my_result['root'] = end($my_host);
			array_pop($my_host);

			// all remain is subdomain
			if(count($my_host) > 0)
			{
				$my_result['subdomain'] = implode('.', $my_host);
			}
		}

		return $my_result;
	}

Solution 28 - Php

Maybe I'm late, but even though the post is old, just as I get to it, many others do.

Today, the wheel is already invented, with a library called php-domain-parser that is active, and in which two mechanisms can be used. One based on the Public Suffix List and one based on the IANA list.

Simple and effective, it allows us to create simple helpers that help us in our project, with the ability to know that the data is maintained, in a world in which the extensions and their variants are very changeable.

Many of the answers given in this post do not pass a battery of unit tests, in which certain current extensions and their variants with multiple levels are checked, and neither with the casuistry of domains with extended characters.

Maybe it serves you, as it served me.

Solution 29 - Php

<?php
// Your code here!

function get_domain($host) {
   $parts = explode('.',$host);
   $extension  = $parts[count($parts)-1];
   $name = $parts[count($parts)-2];
   return  $name.'.'.$extension;
}

echo get_domain("https://api.neoistone.com");
?>

Solution 30 - Php

If you only want what comes before the first period:

list($sub) = explode('.', 'en.example.com', 2);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDamianoView Question on Stackoverflow
Solution 1 - PhpMichael DealView Answer on Stackoverflow
Solution 2 - PhpMike LewisView Answer on Stackoverflow
Solution 3 - PhpmazonView Answer on Stackoverflow
Solution 4 - PhpJMWView Answer on Stackoverflow
Solution 5 - PhpSascha FrinkenView Answer on Stackoverflow
Solution 6 - PhpKamafeatherView Answer on Stackoverflow
Solution 7 - PhpArjenView Answer on Stackoverflow
Solution 8 - PhpJeacovy GayleView Answer on Stackoverflow
Solution 9 - PhpJared FarrishView Answer on Stackoverflow
Solution 10 - PhpOleksandr FediashovView Answer on Stackoverflow
Solution 11 - PhpZulqurnain abbasView Answer on Stackoverflow
Solution 12 - PhpNaseerView Answer on Stackoverflow
Solution 13 - Phpuser3937344View Answer on Stackoverflow
Solution 14 - PhpSebastian SulinskiView Answer on Stackoverflow
Solution 15 - PhpAdam FView Answer on Stackoverflow
Solution 16 - PhpSergio Lopez LoyaView Answer on Stackoverflow
Solution 17 - PhpSheik AlthafView Answer on Stackoverflow
Solution 18 - PhpKhorshed Alam ShohelView Answer on Stackoverflow
Solution 19 - PhpRahul PrasadView Answer on Stackoverflow
Solution 20 - PhpPiccoloView Answer on Stackoverflow
Solution 21 - PhpmohanadView Answer on Stackoverflow
Solution 22 - PhpBrynner FerreiraView Answer on Stackoverflow
Solution 23 - PhptasmaniskiView Answer on Stackoverflow
Solution 24 - PhpitsazzadView Answer on Stackoverflow
Solution 25 - PhpEdwin ThomasView Answer on Stackoverflow
Solution 26 - PhpXIMvadView Answer on Stackoverflow
Solution 27 - PhpMrAdibView Answer on Stackoverflow
Solution 28 - PhpabkrimView Answer on Stackoverflow
Solution 29 - PhpTechnology andriod appsView Answer on Stackoverflow
Solution 30 - PhpMatthewView Answer on Stackoverflow