PHP函数获取URL的子域

发布于 2024-10-21 21:43:37 字数 97 浏览 1 评论 0原文

PHP中有获取子域名的函数吗?

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

en.example.com

Is there a function in PHP to get the name of the subdomain?

In the following example I would like to get the "en" part of the URL:

en.example.com

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(29

薯片软お妹 2024-10-28 21:43:37

这是一个一行解决方案:

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

或者使用您的示例:

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

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

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

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

Here's a one line solution:

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

Or using your example:

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

EDIT: Fixed "only variables should be passed by reference" by adding double parenthesis.

EDIT 2: Starting from PHP 5.4 you can simply do:

explode('.', 'en.example.com')[0];
§对你不离不弃 2024-10-28 21:43:37

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

Uses the parse_url function.

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

$parsedUrl = parse_url($url);

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

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

For multiple subdomains

$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);
帝王念 2024-10-28 21:43:37

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

You can do this by first getting the domain name (e.g. sub.example.com => example.co.uk) and then use strstr to get the subdomains.

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

Outputs:

0 => sub1.sub2
1 => sub1
2 =>
3 => sub1.sub2.sub3
4 => sub1.sub2.sub3
5 => sub1.sub2
淡淡の花香 2024-10-28 21:43:37

http://php.net/parse_url

<?php
  $url = 'http://user:[email protected]/path?argument=value#anchor';
  $array=parse_url($url);
  $array['host']=explode('.', $array['host']);

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

http://php.net/parse_url

<?php
  $url = 'http://user:[email protected]/path?argument=value#anchor';
  $array=parse_url($url);
  $array['host']=explode('.', $array['host']);

  echo $array['host'][0]; // returns 'sub'
?>
猫性小仙女 2024-10-28 21:43:37

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

请在下面找到一个示例。我还添加了 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;

As the only reliable source for domain suffixes are the domain registrars, you can't find the subdomain without their knowledge.
There is a list with all domain suffixes at https://publicsuffix.org. This site also links to a PHP library: https://github.com/jeremykendall/php-domain-parser.

Please find an example below. I also added the sample for en.test.co.uk which is a domain with a multi suffix (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;
萧瑟寒风 2024-10-28 21:43:37

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

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

示例:sub.domain.com

echo $subdomain; 

结果:

echo $host;

结果:

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

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

Example: sub.domain.com

echo $subdomain; 

Result: sub

echo $host;

Result: domain

又怨 2024-10-28 21:43:37

简单...

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

Simply...

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

Just read $match[1]

Working example

It works perfectly with this list of urls

$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);
}
靑春怀旧 2024-10-28 21:43:37

最简单、最快的解决方案。

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

Simplest and fastest solution.

$sSubDomain = str_replace('.example.com','',$_SERVER['HTTP_HOST']);
多孤肩上扛 2024-10-28 21:43:37
$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, '.')); 
$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, '.')); 
累赘 2024-10-28 21:43:37

并没有真正的 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< /代码>。

我希望这有帮助。

There isn't really a 100% dynamic solution - I've just been trying to figure it out as well and due to different domain extensions (DTL) this task would be really difficult without actually parsing all these extensions and checking them each time:

.com vs .co.uk vs org.uk

The most reliable option is to define a constant (or database entry etc.) that stores the actual domain name and remove it from the $_SERVER['SERVER_NAME'] using 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, '.');

}

Now if you're using this function under http://test.mymaindomain.co.uk it will give you test or if you have multiple sub-domain levels http://another.test.mymaindomain.co.uk you'll get another.test - unless of course you update the DOMAIN.

I hope this helps.

自由如风 2024-10-28 21:43:37

使用正则表达式、字符串函数、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'

Using regex, string functions, parse_url() or their combinations it's not real solution. Just test any of proposed solutions with domain test.en.example.co.uk, there will no any correct result.

Correct solution is use package that parses domain with Public Suffix List. I recomend TLDExtract, here is sample code:

$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'
浮生面具三千个 2024-10-28 21:43:37

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

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

What I found the best and short solution is

array_shift(explode(".",$_SERVER['HTTP_HOST']));
云淡风轻 2024-10-28 21:43:37

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

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

For those who get 'Error: Strict Standards: Only variables should be passed by reference.'
Use like this:

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

街角卖回忆 2024-10-28 21:43:37
$domain = 'sub.dev.example.com';
$tmp = explode('.', $domain); // split into parts
$subdomain = current($tmp);
print($subdomain);     // prints "sub"

正如上一个问题中所见:
如何使用 PHP 获取第一个子域?

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

As seen in a previous question:
How to get the first subdomain with PHP?

猥琐帝 2024-10-28 21:43:37

只需

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

Simply

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

旧街凉风 2024-10-28 21:43:37

我正在做这样的事情

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

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

$subdomain = $splitedByDot[0];

I'm doing something like this

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

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

$subdomain = $splitedByDot[0];
楠木可依 2024-10-28 21:43:37

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

Suppose current 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";
    }

記憶穿過時間隧道 2024-10-28 21:43:37

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

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

this is my solution, it works with the most common domains, you can fit the array of extensions as you need:

$SubDomain = explode('.', explode('|ext|', str_replace(array('.com', '.net', '.org'), '|ext|',$_SERVER['HTTP_HOST']))[0]);
请帮我爱他 2024-10-28 21:43:37
// 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
// 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
始终不够 2024-10-28 21:43:37

我知道我真的迟到了,但还是这样吧。

我所做的是获取 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 更好,因为如果子域中有 . ,这不会将其切断。

I know I'm really late to the game, but here goes.

What I did was take the HTTP_HOST server variable ($_SERVER['HTTP_HOST']) and the number of letters in the domain (so for example.com it would be 11).

Then I used the substr function to get the subdomain. I did

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

I cut the substring off at 12 instead of 11 because substrings start on 1 for the second parameter. So now if you entered test.example.com, the value of $subdomain would be test.

This is better than using explode because if the subdomain has a . in it, this will not cut it off.

长途伴 2024-10-28 21:43:37

如果您使用 drupal 7

这将帮助您:

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

if you are using drupal 7

this will help you:

global $base_path;
global $base_root;  
$fulldomain = parse_url($base_root);    
$splitdomain = explode(".", $fulldomain['host']);
$subdomain = $splitdomain[0];
江湖正好 2024-10-28 21:43:37
$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 />';
$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 />';
感性不性感 2024-10-28 21:43:37

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

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

From PHP 5.3 you can use strstr() with true parameter

echo strstr($_SERVER["HTTP_HOST"], '.', true); //prints en
只有一腔孤勇 2024-10-28 21:43:37

试试这个...

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

Try this...

$domain = 'en.example.com';
$tmp = explode('.', $domain);
$subdomain = current($tmp);
echo($subdomain);     // echo "en"
哽咽笑 2024-10-28 21:43:37
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);
}
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);
}
花期渐远 2024-10-28 21:43:37

你也可以用这个

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

you can use this too

echo substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.', -5));
不奢求什么 2024-10-28 21:43:37

也许我迟到了,但尽管这篇文章很旧,但正如我所看到的那样,许多其他人也这样做了。

今天,轮子已经发明了,有一个名为 php-domain-parser 的库是活跃的,并且可以使用两种机制。
一种基于公共后缀列表,另一种基于IANA 列表

简单而有效,它使我们能够创建简单的助手来帮助我们完成项目,并且能够在扩展及其变体非常多变的世界中知道数据是否得到维护。

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

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

Maybe I'm late, but even though the post is old, just as I get to it, many others do.

Today, the wheel is already invented, with a library called php-domain-parser that is active, and in which two mechanisms can be used.
One based on the Public Suffix List and one based on the IANA list.

Simple and effective, it allows us to create simple helpers that help us in our project, with the ability to know that the data is maintained, in a world in which the extensions and their variants are very changeable.

Many of the answers given in this post do not pass a battery of unit tests, in which certain current extensions and their variants with multiple levels are checked, and neither with the casuistry of domains with extended characters.

Maybe it serves you, as it served me.

最美的太阳 2024-10-28 21:43:37
$parts = explode('.', $_SERVER["HTTP_HOST"]);
$subdomain = count($parts) < 3 ? null : $parts[0];
$parts = explode('.', $_SERVER["HTTP_HOST"]);
$subdomain = count($parts) < 3 ? null : $parts[0];
伴梦长久 2024-10-28 21:43:37

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

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

If you only want what comes before the first period:

list($sub) = explode('.', 'en.example.com', 2);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文