PHP函数获取URL的子域名

PHP中有一个函数来获取子域的名称?

在下面的例子中,我想获得URL的“en”部分:

en.example.com 

这是一个单行的解决scheme:

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

或者使用你的例子:

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

编辑:固定“只有variables应通过引用传递”通过添加双括号。

编辑2 :从PHP 5.4开始,你可以简单地做:

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

使用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); 

您可以通过首先获取域名(例如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}\.[az\.]{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 

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

作为域名后缀唯一可靠的来源是域名注册商,你不能在没有他们的知识的情况下find子域名。 在https://publicsuffix.org有一个包含所有域名后缀的列表。; 这个网站也链接到一个PHP库: https : //github.com/jeremykendall/php-domain-parser 。

请在下面find一个例子。 我还为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; 
 $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, '.')); 

只是…

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

只要读$ match [1]

工作示例

它完全适用于这个url列表

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

最简单和最快的解决scheme。

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

我发现最好和最短的解决scheme是

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

对于那些获得“错误:严格标准:只有variables应该通过引用传递”的人。 像这样使用:

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

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

正如前面的问题所示: 如何使用PHP获取第一个子域?

没有一个真正的100%的dynamic解决scheme – 我刚刚试图弄清楚,由于不同的域名扩展(DTL),这个任务将是非常困难的,实际上并没有parsing所有这些扩展,每次检查它们:

.com vs .co.uk vs org.uk

最可靠的select是定义一个存储实际域名的常量(或数据库条目等),并使用substr()$_SERVER['SERVER_NAME']删除它

 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你会得到another.test – 除非你更新DOMAIN

我希望这有帮助。

只是

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

这是我的解决scheme,它与最常见的域一起工作,您可以根据需要安装扩展数组:

$ subDomain = explode('。',explode('| ext |',str_replace(array。'com','.net','.org'),'| ext |',$ _ SERVER ['HTTP_HOST'] ))[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 

我知道我真的很迟到了,但是这里呢。

我所做的是采取HTTP_HOST服务器variables( $_SERVER['HTTP_HOST'] )和域中的字母数量(所以为example.com它将是11)。

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

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

我将子string从12减less到11,因为子string从1开始为第二个参数。 所以现在如果你inputtest.example.com, $subdomain的值将被test

这比使用explode更好,因为如果子域有一个. 在这一点上,这不会割断它。

如果你使用的是drupal 7

这将帮助你:

 global $base_path; global $base_root; $fulldomain = parse_url($base_root); $splitdomain = explode(".", $fulldomain['host']); $subdomain = $splitdomain[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 />'; 

从PHP 5.3开始,可以使用带有true参数的strstr()

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

尝试这个…

 $domain = 'en.example.com'; $tmp = explode('.', $domain); $subdomain = current($tmp); echo($subdomain); // echo "en" 
 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); } 

使用正则expression式,string函数,parse_url()或它们的组合,这不是真正的解决scheme。 只要用domain test.en.example.co.uktesting任何build议的解决scheme,就没有任何正确的结果。

正确的解决scheme是使用公共后缀列表parsing域的使用包。 我build议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' 

你也可以使用它

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

如果你只想要在第一个时期之前发生的事情:

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