PHP从子域获取域名
我需要写一个函数来解析包含域名的变量。我最好用一个例子来解释这一点,变量可以包含以下任何内容:PHP从子域获取域名,php,dns,subdomain,Php,Dns,Subdomain,我需要写一个函数来解析包含域名的变量。我最好用一个例子来解释这一点,变量可以包含以下任何内容: here.example.com example.com example.org here.example.org 但是当通过我的函数时,所有这些都必须返回example.com或example.co.uk,根域名。我肯定我以前做过,但我在谷歌搜索了大约20分钟,什么也找不到。任何帮助都将不胜感激 编辑:忽略.co.uk,假设所有通过此功能的域都有一个3个字母的TLD。Stackoverflow问题
here.example.com
example.com
example.org
here.example.org
但是当通过我的函数时,所有这些都必须返回example.com或example.co.uk,根域名。我肯定我以前做过,但我在谷歌搜索了大约20分钟,什么也找不到。任何帮助都将不胜感激
编辑:忽略.co.uk,假设所有通过此功能的域都有一个3个字母的TLD。Stackoverflow问题存档:
打印获取域(“http://somedomain.co.uk"); // 输出“somedomain.co.uk”
函数get_domain($url)
{
$pieces=parse_url($url);
$domain=isset($pieces['host'])?$pieces['host']:'';
if(preg_match('/(?P[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i',$domain,$regs)){
返回$regs['domain'];
}
返回false;
}
正则表达式可以帮助您。试着这样做:
([^.]+(.com |.co.uk))$我认为您的问题在于您没有明确定义您希望函数做什么。从您的示例中,您当然不希望它盲目地返回名称的最后两个或最后三个组件,但仅仅知道它不应该做什么是不够的 以下是我对您真正想要的内容的猜测:有一些二级域名,如
co.uk.
,您希望将其视为一个TLD(顶级域名),以实现此功能。在这种情况下,我建议列举所有此类情况,并将它们作为键放入具有虚拟值的关联数组中,以及所有正常的顶级域,如com.
,net.
,info.
,等等。然后,每当您获得新域名,提取最后两个组件,并查看结果字符串是否作为键存在于数组中。如果没有,则只提取最后一个组件,并确保它在数组中。(即使不是,它也不是一个有效的域名)无论如何,不管你在数组中找到了什么密钥,从域名的末尾再加上一个组件,你就拥有了你的基本域名
也许,您可以编写一个函数,而不是使用关联数组,来判断最后两个组件是否应被视为一个“有效TLD”,从而使事情变得更简单。该函数可能会查看下一个到最后一个组件,如果它短于3个字符,决定将其视为TLD的一部分。我将执行以下操作:
// hierarchical array of top level domains
$tlds = array(
'com' => true,
'uk' => array(
'co' => true,
// …
),
// …
);
$domain = 'here.example.co.uk';
// split domain
$parts = explode('.', $domain);
$tmp = $tlds;
// travers the tree in reverse order, from right to left
foreach (array_reverse($parts) as $key => $part) {
if (isset($tmp[$part])) {
$tmp = $tmp[$part];
} else {
break;
}
}
// build the result
var_dump(implode('.', array_slice($parts, - $key - 1)));
为了做好这项工作,您需要一个二级域和顶级域的列表,并构建一个适当的正则表达式列表。有关二级域的详细列表,请访问。除了上述CentralNic.uk.com变体之外,另一个测试用例是梵蒂冈:他们的网站技术上位于:这是一个很难匹配的网站 Ah-如果您只想处理三个字符的顶级域,那么下面的代码可以工作:
<?php
// let's test the code works: these should all return
// example.com , example.net or example.org
$domains=Array('here.example.com',
'example.com',
'example.org',
'here.example.org',
'example.com/ignorethis',
'example.net/',
'http://here.example.org/longtest?string=here');
foreach ($domains as $domain) {
testdomain($domain);
}
function testdomain($url) {
if (preg_match('/^((.+)\.)?([A-Za-z][0-9A-Za-z\-]{1,63})\.([A-Za-z]{3})(\/.*)?$/',$url,$matches)) {
print 'Domain is: '.$matches[3].'.'.$matches[4].'<br>'."\n";
} else {
print 'Domain not found in '.$url.'<br>'."\n";
}
}
?>
或者让它应对一切:
if (preg_match('/^((.+)\.)?([A-Za-z][0-9A-Za-z\-]{1,63})\.(co\.uk|me\.uk|org\.uk|com|org|net|int|eu)(\/.*)?$/',$url,$matches)) {
etc等基于乔纳森的回答:
function main_domain($domain) {
if (preg_match('/([a-z0-9][a-z0-9\-]{1,63})\.([a-z]{3}|[a-z]{2}\.[a-z]{2})$/i', $domain, $regs)) {
return $regs;
}
return false;
}
他的表达方式可能会更好一些,但这个界面看起来更像您所描述的。几乎可以肯定,您要寻找的是:
function isTopLevelDomain($domain)
{
$domainParts = explode('.', $domain);
if (count($domainParts) == 1) {
return false;
}
$previousDomainParts = $domainParts;
array_shift($previousDomainParts);
$tld = implode('.', $previousDomainParts);
return isDomainExtension($tld);
}
function isDomainExtension($domain)
{
$tlds = getTLDs();
/**
* direct hit
*/
if (in_array($domain, $tlds)) {
return true;
}
if (in_array('!'. $domain, $tlds)) {
return false;
}
$domainParts = explode('.', $domain);
if (count($domainParts) == 1) {
return false;
}
$previousDomainParts = $domainParts;
array_shift($previousDomainParts);
array_unshift($previousDomainParts, '*');
$wildcardDomain = implode('.', $previousDomainParts);
return in_array($wildcardDomain, $tlds);
}
function getTLDs()
{
static $mozillaTlds = array();
if (empty($mozillaTlds)) {
require 'fetch_mozilla_tlds.php';
/* @var $mozillaTlds array */
}
return $mozillaTlds;
}
这是一个PHP库,它利用了publicsuffix.org/list/上收集的各种TLD的完整列表(尽可能实际),并将其封装在一个漂亮的小函数中
一旦包含了库,就可以轻松地执行以下操作:
$registeredDomain=getRegisteredDomain($domain)代码>以下是从任何URL中删除TLD的方法-我编写代码是为了在我的网站上工作:
-这是一个在我的网站上使用的工作解决方案。
$host是必须解析的URL。此代码是一个简单且可靠的解决方案
与我所看到的所有其他内容相比,它适用于我尝试过的任何URL
请参阅下面的代码,解析您正在查看的页面
================================================================================
$host = filter_var($_GET['dns']);
$host = $host . '/'; // needed if URL does not have trailing slash
// Strip www, http, https header ;
$host = str_replace( 'http://www.' , '' , $host );
$host = str_replace( 'https://www.' , '' , $host );
$host = str_replace( 'http://' , '' , $host );
$host = str_replace( 'https://' , '' , $host );
$pos = strpos($host, '/'); // find any sub directories
$host = substr( $host, 0, $pos ); //strip directories
$hostArray = explode (".", $host); // count parts of TLD
$size = count ($hostArray) -1; // really only need to know if not a single level TLD
$tld = $hostArray[$size]; // do we need to parse the TLD any further -
// remove subdomains?
if ($size > 1) {
if ($tld == "aero" or $tld == "asia" or $tld == "biz" or $tld == "cat" or
$tld == "com" or $tld == "coop" or $tld == "edu" or $tld == "gov" or
$tld == "info" or $tld == "int" or $tld == "jobs" or $tld == "me" or
$tld == "mil" or $tld == "mobi" or $tld == "museum" or $tld == "name" or
$tld == "net" or $tld == "org" or $tld == "pro" or $tld == "tel" or
$tld == "travel" or $tld == "tv" or $tld == "ws" or $tld == "XXX") {
$host = $hostArray[$size -1].".".$hostArray[$size]; // parse to 2 level TLD
} else {
// parse to 3 level TLD
$host = $hostArray[$size -2].".".$hostArray[$size -1].".".$hostArray[$size] ;
}
}
基于
作为乔纳森·桑普森的变种
function get_domain($url) {
if ( !preg_match("/^http/", $url) )
$url = 'http://' . $url;
if ( $url[strlen($url)-1] != '/' )
$url .= '/';
$pieces = parse_url($url);
$domain = isset($pieces['host']) ? $pieces['host'] : '';
if ( preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs) ) {
$res = preg_replace('/^www\./', '', $regs['domain'] );
return $res;
}
return false;
}
函数获取域($url){
如果(!preg_match(“/^http/”,$url))
$url='http://'。$url;
如果($url[strlen($url)-1]!='/'))
$url.='/';
$pieces=parse_url($url);
$domain=isset($pieces['host'])?$pieces['host']:'';
如果(preg_match('/(?P[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i',$domain,$regs)){
$res=preg_replace(“/^www./”,“$regs['domain']);
返回$res;
}
返回false;
}
以下是我正在使用的:
它在tld不需要任何阵列的情况下工作得很好
$split = array_reverse(explode(".", $_SERVER['HTTP_HOST']));
$domain = $split[1].".".$split[0];
if(function_exists('gethostbyname'))
{
if(gethostbyname($domain) != $_SERVER['SERVER_ADDR'] && isset($split[2]))
{
$domain = $split[2].".".$split[1].".".$split[0];
}
}
不使用TLD列表进行比较是不可能的,因为它们存在许多类似的情况
或
但即使这样,你也不会因为喜欢或不喜欢而在任何情况下都取得成功
如果您需要完整的列表,可以使用:
请随意使用我的功能。它不会使用正则表达式,而且速度很快:
此脚本生成一个Perl文件,其中包含一个函数,即从ETLD文件获取域。假设你有像img1,img2,img3这样的主机名。。。在photobucket.com。对于每个get_域,$host将返回photobucket.com。请注意,这并不是地球上最快的函数,因此在使用它的主日志解析器中,我保留了主机到域映射的哈希,并且只对尚未在哈希中的主机运行此函数
#!/bin/bash
cat << 'EOT' > suffixes.pl
#!/bin/perl
sub get_domain {
$_ = shift;
EOT
wget -O - http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1 \
| iconv -c -f UTF-8 -t ASCII//TRANSLIT \
| egrep -v '/|^$' \
| sed -e 's/^\!//' -e "s/\"/'/g" \
| awk '{ print length($0),$0 | "sort -rn"}' | cut -d" " -f2- \
| while read SUFF; do
STAR=`echo $SUFF | cut -b1`
if [ "$STAR" = '*' ]; then
SUFF=`echo $SUFF | cut -b3-`
echo " return \"\$1\.\$2\.$SUFF\" if /([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-]+)\.$SUFF\$/;"
else
echo " return \"\$1\.$SUFF\" if /([a-zA-Z0-9\-]+)\.$SUFF\$/;"
fi
done >> suffixes.pl
cat << 'EOT' >> suffixes.pl
}
1;
EOT
#/bin/bash
cat后缀.pl
#!/bin/perl
子域{
$=移位;
EOT
wget-O-http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1 \
|iconv-c-f UTF-8-t ASCII//translatit\
|白鹭-v'/^$'\
|sed-e's/^\!/'-e“s/\“/'/g”\
|awk'{打印长度($0),$0 |“sort-rn”}'| cut-d'-f2-\
|边读边做
星形=`echo$SUFF | cut-b1`
如果[“$STAR”=“*”],则
function get_domain($url) {
if ( !preg_match("/^http/", $url) )
$url = 'http://' . $url;
if ( $url[strlen($url)-1] != '/' )
$url .= '/';
$pieces = parse_url($url);
$domain = isset($pieces['host']) ? $pieces['host'] : '';
if ( preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs) ) {
$res = preg_replace('/^www\./', '', $regs['domain'] );
return $res;
}
return false;
}
$split = array_reverse(explode(".", $_SERVER['HTTP_HOST']));
$domain = $split[1].".".$split[0];
if(function_exists('gethostbyname'))
{
if(gethostbyname($domain) != $_SERVER['SERVER_ADDR'] && isset($split[2]))
{
$domain = $split[2].".".$split[1].".".$split[0];
}
}
#!/bin/bash
cat << 'EOT' > suffixes.pl
#!/bin/perl
sub get_domain {
$_ = shift;
EOT
wget -O - http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1 \
| iconv -c -f UTF-8 -t ASCII//TRANSLIT \
| egrep -v '/|^$' \
| sed -e 's/^\!//' -e "s/\"/'/g" \
| awk '{ print length($0),$0 | "sort -rn"}' | cut -d" " -f2- \
| while read SUFF; do
STAR=`echo $SUFF | cut -b1`
if [ "$STAR" = '*' ]; then
SUFF=`echo $SUFF | cut -b3-`
echo " return \"\$1\.\$2\.$SUFF\" if /([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-]+)\.$SUFF\$/;"
else
echo " return \"\$1\.$SUFF\" if /([a-zA-Z0-9\-]+)\.$SUFF\$/;"
fi
done >> suffixes.pl
cat << 'EOT' >> suffixes.pl
}
1;
EOT
$mozillaTlds = file('http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1');
function isTopLevelDomain($domain)
{
$domainParts = explode('.', $domain);
if (count($domainParts) == 1) {
return false;
}
$previousDomainParts = $domainParts;
array_shift($previousDomainParts);
$tld = implode('.', $previousDomainParts);
return isDomainExtension($tld);
}
function isDomainExtension($domain)
{
$tlds = getTLDs();
/**
* direct hit
*/
if (in_array($domain, $tlds)) {
return true;
}
if (in_array('!'. $domain, $tlds)) {
return false;
}
$domainParts = explode('.', $domain);
if (count($domainParts) == 1) {
return false;
}
$previousDomainParts = $domainParts;
array_shift($previousDomainParts);
array_unshift($previousDomainParts, '*');
$wildcardDomain = implode('.', $previousDomainParts);
return in_array($wildcardDomain, $tlds);
}
function getTLDs()
{
static $mozillaTlds = array();
if (empty($mozillaTlds)) {
require 'fetch_mozilla_tlds.php';
/* @var $mozillaTlds array */
}
return $mozillaTlds;
}
$host = $_SERVER['HTTP_HOST'];
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
echo "domain name is: {$matches[0]}\n";
$extract = new LayerShifter\TLDExtract\Extract();
$result = $extract->parse('here.example.com');
$result->getSubdomain(); // will return (string) 'here'
$result->getHostname(); // will return (string) 'example'
$result->getSuffix(); // will return (string) 'com'
function get_domaininfo($url) {
// regex can be replaced with parse_url
preg_match("/^(https|http|ftp):\/\/(.*?)\//", "$url/" , $matches);
$parts = explode(".", $matches[2]);
$tld = array_pop($parts);
$host = array_pop($parts);
if ( strlen($tld) == 2 && strlen($host) <= 3 ) {
$tld = "$host.$tld";
$host = array_pop($parts);
}
return array(
'protocol' => $matches[1],
'subdomain' => implode(".", $parts),
'domain' => "$host.$tld",
'host'=>$host,'tld'=>$tld
);
}
print_r(get_domaininfo('http://mysubdomain.domain.co.uk/index.php'));
Array
(
[protocol] => https
[subdomain] => mysubdomain
[domain] => domain.co.uk
[host] => domain
[tld] => co.uk
)
$justDomain = $_SERVER['SERVER_NAME'];
switch(substr_count($justDomain, '.')) {
case 1:
// 2 parts. Must not be a subdomain. Do nothing.
break;
case 2:
// 3 parts. Either a subdomain or a 2-part suffix
// If the 2nd part is over 3 chars's, assume it to be the main domain part which means we have a subdomain.
// This isn't foolproof, but should be ok for most domains.
// Something like domainname.parliament.nz would cause problems, though. As would www.abc.com
$parts = explode('.', $justDomain);
if(strlen($parts[1]) > 3) {
unset($parts[0]);
$justDomain = implode('.', $parts);
}
break;
default:
// 4+ parts. Must be a subdomain.
$parts = explode('.', $justDomain, 2);
$justDomain = $parts[1];
break;
}
// $justDomain should now exclude any subdomain part.
function get_domain($host){
$myhost = strtolower(trim($host));
$count = substr_count($myhost, '.');
if($count === 2){
if(strlen(explode('.', $myhost)[1]) > 3) $myhost = explode('.', $myhost, 2)[1];
} else if($count > 2){
$myhost = get_domain(explode('.', $myhost, 2)[1]);
}
return $myhost;
}
echo parse_url($your_url)['host'];
//For short domain like t.co (twitter) the function should be :
function get_domain($url)
{
$pieces = parse_url($url);
$domain = isset($pieces['host']) ? $pieces['host'] : '';
if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{0,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) {
return $regs['domain'];
}
return false;
}