Search code examples
phphtmlregexsubdomainserver-name

Get Sub-domain with PHP


How to get sub domain from URL. let say subdomain.example.com, then i want only subdomain

Example :

https://subdomain.example.com
https://anything.example.com/pathurl

Output :

Subdomain
anything

Trying code from stackoverflow with some modification but did not work :(

$subdomain = substr($_SERVER['SERVER_NAME'],0,4) === '/^([^.]+)/' ? substr($_SERVER['SERVER_NAME'],0) : $_SERVER['SERVER_NAME'];
echo $subdomain;

Solution

  • Firstly, to break down your attempt:

    • $_SERVER['SERVER_NAME'] gives you the full server name, e.g. "subdomain.example.com"
    • substr($_SERVER['SERVER_NAME'],0,4) gives you the first four characters of that string; it's likely the example you copied from was looking for "www.", which is four characters long, but "subd" isn't going to tell you much
    • === just compares that two things are identical; since you've just asked for four characters, it's never going to match a string of any other length
    • '/^([^.]+)/' looks like a Regular Expression (aka "regex") - a pattern to match strings; to use that in PHP, you need the PCRE family of functions, such as preg_match and preg_replace

    Next, the tip I always give: break the problem down. Forget for a moment that you know what a sub-domain is, and notice that you have a string, and want all the text up to the first dot.

    One way to get that is therefore to split the string on every dot, and take the first part. For that, you would use the excitingly named explode:

    $subdomain = explode('.', $fulldomain, 1)[0];
    

    Another way would be using the regex pattern you found, which reads "starting at the beginning, match anything but a dot, at least once, and capture that part". You can actually skip one pair of brackets, because they're grouping the whole pattern, so just '/^[^.]+/' is enough. To do that, you'd use preg_match, but note that it doesn't return the matched parts, it puts them in an extra array you pass to it:

    $matches = null; // will be populated by preg_match
    preg_match('/^[^.]+/', $fulldomain, $matches);
    $subdomain = $matches[0];
    

    Note: The above will return "stackoverflow" for an input of "stackoverflow.com". That is unavoidable with simple string matching, because there is no standard number of segments that mark a "public domain" - e.g. "bbc.co.uk" is registered at the same level as "bbc.com", but you can't tell that by looking at them. Unless you know in advance what your possible endings will be, you need something that checks the Public Suffix List, such as the php-domain-parser library.