函数获取 URL 的子域

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

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

en.example.com
159740 次浏览

如果你只想要第一节课之前的东西:

list($sub) = explode('.', 'en.example.com', 2);
$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, '.'));

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

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

这里有一个简单的解决办法:

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

或者用你的例子:

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

编辑: 通过添加双括号修正了“只有变量应该通过引用传递”的问题。


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

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

您可以通过首先获取域名(例如 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

我找到的最好和最短的解决办法是

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

最简单最快的解决方案。

$sSubDomain = str_replace('.example.com','',$_SERVER['HTTP_HOST']);
// 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 服务器变量($_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要好,因为如果子域中有一个 .,这将不会切断它。

如果你使用的是 Drupal 7

这会帮助你:

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

对于那些得到‘错误: 严格的标准: 只有变量应该通过引用传递。’ 使用方法如下:

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

$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中,可以使用带有 没错参数的 Strstr ()

echo strstr($_SERVER["HTTP_HOST"], '.', true); //prints 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);
}

试试这个..。

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

很简单。

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

由于域后缀的唯一可靠来源是域注册者,如果没有他们的知识,您就无法找到子域。 在 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;
$domain = 'sub.dev.example.com';
$tmp = explode('.', $domain); // split into parts
$subdomain = current($tmp);
print($subdomain);     // prints "sub"

如前面的问题所示: 如何获得第一个子域与 PHP?

没有一个真正的100% 动态解决方案——我也一直在试图弄明白,由于不同的域扩展(DTL) ,如果不解析所有这些扩展并每次检查它们,这项任务将非常困难:

.com vs .co.uk vs org.uk

最可靠的选择是定义一个常量(或者数据库条目等)来存储实际的域名,并使用 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

I hope this helps.

很简单

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

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

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

使用正则表达式、字符串函数、 parse _ url ()或它们的组合并不是真正的解决方案。只要使用域 test.en.example.co.uk测试任何提出的解决方案,就不会有任何正确的结果。

正确的解决方案是使用包解析域与 公开后缀名单。我建议 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));

我正在做类似的事情

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


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


$subdomain = $splitedByDot[0];

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

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

示例: sub.domain.com

echo $subdomain;

结果: sub

echo $host;

Result: domain

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


也许我迟到了,但是即使这个帖子已经很旧了,当我到达它的时候,很多人都这样做了。

今天,车轮已经被发明,有一个名为 域解析器的库是活跃的,其中可以使用两种机制。 一个基于 公开后缀名单,一个基于 IANA list

简单而有效,它允许我们创建简单的帮助程序来帮助我们的项目,并且能够知道数据是维护的,在这个世界中,扩展及其变体是非常可变的。

本文中给出的许多答案都没有通过一系列的单元测试,在这些单元测试中,某些当前扩展及其具有多个级别的变体都会被检查,而具有扩展字符的域名也不会被检查。

也许它为你服务,就像它为我服务一样。

<?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");
?>