PHP函数来获取URL的子域

时间:2011-03-13 22:36:06

标签: php subdomain

PHP中是否有一个函数来获取子域名?

在以下示例中,我想获取URL的“en”部分:

en.example.com

28 个答案:

答案 0 :(得分:121)

这是一个单行解决方案:

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

或使用您的示例:

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

编辑:通过添加双括号修复“只应通过引用传递变量”。


EDIT 2 :从PHP 5.4开始,你可以做到:

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

答案 1 :(得分:59)

使用parse_url功能。

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

$parsedUrl = parse_url($url);

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

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

适用于多个子域

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

答案 2 :(得分:32)

您可以先获取域名(例如sub.example.com => example.co.uk),然后使用strstr获取子域名。

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

输出:

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

答案 3 :(得分:10)

http://php.net/parse_url

<?php
  $url = 'http://user:password@sub.hostname.tld/path?argument=value#anchor';
  $array=parse_url($url);
  $array['host']=explode('.', $array['host']);

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

答案 4 :(得分:6)

作为域名后缀的唯一可靠来源是域名注册商,您无法在他们不知情的情况下找到子域名。 在https://publicsuffix.org有一个包含所有域后缀的列表。该站点还链接到PHP库:https://github.com/jeremykendall/php-domain-parser

请在下面找到一个例子。我还为en.test.co.uk添加了样本,这是一个带有多重后缀的域名(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;

答案 5 :(得分:4)

最简单,最快速的解决方案。

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

答案 6 :(得分:4)

只需...

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

只需阅读 $ match [1]

工作示例

它与此网址列表完美配合

$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);
}

答案 7 :(得分:3)

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

答案 8 :(得分:1)

实际上并非100%动态的解决方案 - 我一直试图弄清楚它并且由于不同的域扩展(DTL),如果不实际解析所有这些任务,这项任务将非常困难扩展并每次检查它们:

.com vs .co.uk vs org.uk

最可靠的选择是定义存储实际域名的常量(或数据库条目等),并使用$_SERVER['SERVER_NAME']

将其从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, '.');

}

现在,如果您在http://test.mymaindomain.co.uk下使用此功能,它将为您提供test,或者如果您有多个子域级别http://another.test.mymaindomain.co.uk,那么您将获得{{} 1}} - 除非您更新another.test

我希望这会有所帮助。

答案 9 :(得分:1)

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

如前一个问题所示: How to get the first subdomain with PHP?

答案 10 :(得分:1)

简单地

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

答案 11 :(得分:1)

这是我的解决方案,它适用于最常见的域,您可以根据需要调整扩展数组:

$ SubDomain = explode(&#39;。&#39;,explode(&#39; | ext |&#39;,str_replace(array(&#39; .com&#39;,&#39; .net&#39;,&#39; .org&#39;),&#39; | ext |&#39;,$ _ SERVER [&#39; HTTP_HOST&#39;]))[0]);

答案 12 :(得分:1)

使用正则表达式,字符串函数,parse_url()或它们的组合,它不是真正的解决方案。只需使用域test.en.example.co.uk测试任何建议的解决方案,就不会有任何正确的结果。

正确的解决方案是使用使用Public Suffix List解析域的包。我推荐TLDExtract,这里是示例代码:

$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'

答案 13 :(得分:1)

对于那些得到'错误:严格标准:只应通过引用传递变量'的人。 使用方式如下:

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

答案 14 :(得分:1)

我发现最好的简短解决方案是

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

答案 15 :(得分:0)

你也可以使用它

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

答案 16 :(得分:0)

我正在做这样的事情

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

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

$subdomain = $splitedByDot[0];

答案 17 :(得分:0)

PHP 7.0:使用explode函数并创建所有结果的列表。

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

示例:sub.domain.com

echo $subdomain; 

结果:sub

echo $host;

结果:域

答案 18 :(得分:0)

我们使用此功能处理多个子域多个tld 也处理ip和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;
    }

答案 19 :(得分:0)

假设当前网址= 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";
    }

答案 20 :(得分:0)

试试这个......

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

答案 21 :(得分:0)

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

答案 22 :(得分:0)

从PHP 5.3开始,您可以将 strstr() true 参数

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

答案 23 :(得分:0)

$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 />';

答案 24 :(得分:0)

如果您使用的是drupal 7

这将对您有所帮助:

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

答案 25 :(得分:0)

我知道我在比赛中已经很晚了,但现在就去了。

我所做的是获取HTTP_HOST服务器变量($_SERVER['HTTP_HOST'])和域中的字母数(因此对于example.com它将是11)。

然后我使用substr函数来获取子域。我做了

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

我将子字符串关闭为12而不是11,因为子字符串从1开始为第二个参数。现在,如果您输入test.example.com,$subdomain的值将为test

这比使用explode更好,因为如果子域中包含.,则不会将其删除。

答案 26 :(得分:0)

// 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

答案 27 :(得分:-3)

如果您只想要第一个时期之前的内容:

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