PHP中是否有一个函数来获取子域的名称?
在下面的示例中,我想获取URL的“ en”部分:
en.example.com
(^|://)(.*)\.
捕获.*
吗?我宁愿同时吸取php和regex,但这是想到的。
en.foo.bar.example.com
还是en.example.co.uk
?
PHP中是否有一个函数来获取子域的名称?
在下面的示例中,我想获取URL的“ en”部分:
en.example.com
(^|://)(.*)\.
捕获.*
吗?我宁愿同时吸取php和regex,但这是想到的。
en.foo.bar.example.com
还是en.example.co.uk
?
Answers:
这是一线解决方案:
array_shift((explode('.', $_SERVER['HTTP_HOST'])));
或使用您的示例:
array_shift((explode('.', 'en.example.com')));
编辑:通过添加双括号修复了“仅变量应通过引用传递”。
编辑2:从PHP 5.4开始,您可以简单地执行以下操作:
explode('.', 'en.example.com')[0];
explode(...)[0]
这些天,您难道不能只做轮班吗?没有PHPing几年..
Strict Standards: Only variables should be passed by reference.
www.en.example.com
,因此将www
作为子域返回。
使用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}\.[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
for
循环获取数组的最后一个元素来制定自己的解决方案,但是我必须检查它们的长度(以检测它们的长度)是域名的一部分,例如“ co.uk”)。实际上,您的解决方案比我所做的要简单得多。正则表达式可以挽救生命,谢谢!
<?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'
?>
作为域后缀的唯一可靠来源是域注册商,因此在没有子域名的情况下您无法找到子域。在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;
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);
}
.ua
是乌克兰的国家代码。
$match[1]
一部分吗?$match[0]
似乎没有必要。
$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, '.'));
$_SERVER['HTTP_HOST']
假设这就是答案背后的基本思想,那么有更好的方法可以自动检测当前主机(例如),然后依靠可欺骗的引荐来源标头。
PHP 7.0:使用爆炸功能并创建所有结果的列表。
list($subdomain,$host) = explode('.', $_SERVER["SERVER_NAME"]);
示例:sub.domain.com
echo $subdomain;
结果:子
echo $host;
结果:域
.co.uk
-您的代码段无法使用这些顶级域名(TLD)
我发现最好的短期解决方案是
array_shift(explode(".",$_SERVER['HTTP_HOST']));
对于那些“错误:严格的标准:仅变量应通过引用传递”的人。像这样使用:
$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%动态解决方案-我也一直在尝试解决这个问题,由于域扩展名(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
获得another.test
-除非您当然更新DOMAIN
。
我希望这有帮助。
使用正则表达式,字符串函数,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'
这是我的解决方案,它适用于最常见的域,您可以根据需要容纳一系列扩展:
$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服务器变量($_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
因为如果子域中有一个.
,则不会切断它。
$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()与true参数一起使用
echo strstr($_SERVER["HTTP_HOST"], '.', true); //prints en
www
字符串开头没有时,这才起作用。过于琐碎的方法。
www
是实际上是一个子域。由于历史原因,它通常只是域名的别名。
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);
}
$host = explode('.', isset($parsedUrl['path']) ? $parsedUrl['path'] : $parsedUrl['host']);
我正在做这样的事情
$url = https://en.example.com
$splitedBySlash = explode('/', $url);
$splitedByDot = explode('.', $splitedBySlash[2]);
$subdomain = $splitedByDot[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;
}
假设当前网址= sub.example.com
$ host = array_reverse(explode('。',$ _SERVER ['SERVER_NAME']))); 如果(count($ host)> = 3){ echo“主域为=”。$ host [1]。“。”。$ host [0]。“&子域为=”。$ host [2]; //主域名为= example.com,子域名为=子域名 }其他{ echo“主域为=”。$ host [1]。“。”。$ host [0]。“&子域未找到”; //“主域名为= example.com&未找到子域名”; }
如果您只想要第一期之前的内容:
list($sub) = explode('.', 'en.example.com', 2);
parse_url()
来提取主机。