【问题标题】:PHP get domain from URLPHP 从 URL 获取域
【发布时间】:2014-12-27 17:22:51
【问题描述】:

我在网上(也在这里)寻找从 URL 获取域的所有可能功能。 我找到的最新代码来自这里 - https://gist.github.com/pocesar/5366899

            <?php
            /**
             * @param string $domain Pass $_SERVER['SERVER_NAME'] here
             * @param bool $debug
             *
             * @debug bool $debug
             * @return string
             */
            function get_domain($domain, $debug = false)
            {
                $original = $domain = strtolower($domain);

                if (filter_var($domain, FILTER_VALIDATE_IP)) { return $domain; }

                $debug ? print('<strong style="color:green">&raquo;</strong> Parsing: '.$original) : false;

                $arr = array_slice(array_filter(explode('.', $domain, 4), function($value){
                    return $value !== 'www';
                }), 0); //rebuild array indexes

                if (count($arr) > 2)
                {
                    $count = count($arr);
                    $_sub = explode('.', $count === 4 ? $arr[3] : $arr[2]);

                    $debug ? print(" (parts count: {$count})") : false;

                    if (count($_sub) === 2) // two level TLD
                    {
                        $removed = array_shift($arr);
                        if ($count === 4) // got a subdomain acting as a domain
                        {
                            $removed = array_shift($arr);
                        }
                        $debug ? print("<br>\n" . '[*] Two level TLD: <strong>' . join('.', $_sub) . '</strong> ') : false;
                    }
                    elseif (count($_sub) === 1) // one level TLD
                    {
                        $removed = array_shift($arr); //remove the subdomain

                        if (strlen($_sub[0]) === 2 && $count === 3) // TLD domain must be 2 letters
                        {
                            array_unshift($arr, $removed);
                        }
                        else
                        {
                            // non country TLD according to IANA
                            $tlds = array(
                                'aero',
                                'arpa',
                                'asia',
                                'biz',
                                'cat',
                                'com',
                                'coop',
                                'edu',
                                'gov',
                                'info',
                                'jobs',
                                'mil',
                                'mobi',
                                'museum',
                                'name',
                                'net',
                                'org',
                                'post',
                                'pro',
                                'tel',
                                'travel',
                                'xxx',
                            );

                            if (count($arr) > 2 && in_array($_sub[0], $tlds) !== false) //special TLD don't have a country
                            {
                                array_shift($arr);
                            }
                        }
                        $debug ? print("<br>\n" .'[*] One level TLD: <strong>'.join('.', $_sub).'</strong> ') : false;
                    }
                    else // more than 3 levels, something is wrong
                    {
                        for ($i = count($_sub); $i > 1; $i--)
                        {
                            $removed = array_shift($arr);
                        }
                        $debug ? print("<br>\n" . '[*] Three level TLD: <strong>' . join('.', $_sub) . '</strong> ') : false;
                    }
                }
                elseif (count($arr) === 2)
                {
                    $arr0 = array_shift($arr);

                    if (strpos(join('.', $arr), '.') === false
                        && in_array($arr[0], array('localhost','test','invalid')) === false) // not a reserved domain
                    {
                        $debug ? print("<br>\n" .'Seems invalid domain: <strong>'.join('.', $arr).'</strong> re-adding: <strong>'.$arr0.'</strong> ') : false;
                        // seems invalid domain, restore it
                        array_unshift($arr, $arr0);
                    }
                }

                $debug ? print("<br>\n".'<strong style="color:gray">&laquo;</strong> Done parsing: <span style="color:red">' . $original . '</span> as <span style="color:blue">'. join('.', $arr) ."</span><br>\n") : false;

                return join('.', $arr);
            }

            $urls = array(
                'www.example.com' => 'example.com',
                'example.com' => 'example.com',
                'example.com.br' => 'example.com.br',
                'www.example.com.br' => 'example.com.br',
                'www.example.gov.br' => 'example.gov.br',
                'localhost' => 'localhost',
                'www.localhost' => 'localhost',
                'subdomain.localhost' => 'localhost',
                'www.subdomain.example.com' => 'example.com',
                'subdomain.example.com' => 'example.com',
                'subdomain.example.com.br' => 'example.com.br',
                'www.subdomain.example.com.br' => 'example.com.br',
                'www.subdomain.example.biz.br' => 'example.biz.br',
                'subdomain.example.biz.br' => 'example.biz.br',
                'subdomain.example.net' => 'example.net',
                'www.subdomain.example.net' => 'example.net',
                'www.subdomain.example.co.kr' => 'example.co.kr',
                'subdomain.example.co.kr' => 'example.co.kr',
                'example.co.kr' => 'example.co.kr',
                'example.jobs' => 'example.jobs',
                'www.example.jobs' => 'example.jobs',
                'subdomain.example.jobs' => 'example.jobs',
                'insane.subdomain.example.jobs' => 'example.jobs',
                'insane.subdomain.example.com.br' => 'example.com.br',
                'www.doubleinsane.subdomain.example.com.br' => 'example.com.br',
                'www.subdomain.example.jobs' => 'example.jobs',
                'test' => 'test',
                'www.test' => 'test',
                'subdomain.test' => 'test',
                'www.detran.sp.gov.br' => 'sp.gov.br',
                'www.mp.sp.gov.br' => 'sp.gov.br',
                'ny.library.museum' => 'library.museum',
                'www.ny.library.museum' => 'library.museum',
                'ny.ny.library.museum' => 'library.museum',
                'www.library.museum' => 'library.museum',
                'info.abril.com.br' => 'abril.com.br',
                '127.0.0.1' => '127.0.0.1',
                '::1' => '::1',
            );

            $failed = 0;
            $total = count($urls);

            foreach ($urls as $from => $expected)
            {
                $from = get_domain($from, true);
                if ($from !== $expected)
                {
                    $failed++;
                    print("<div style='color:fuchsia;'>expected {$from} to be {$expected}</div>");
                }
            }

            if ($failed)
            {
                print("{$failed} tests failed out of {$total}");
            }
            else
            {
                print("Success");
            }

但我发现在这些情况下它不起作用:

blog.ebaum.tv
api.outside.in
chip.cuccio.us
brushes.net.tc
beta.wua.la
core.windows.net
dd.cron.ru
compute-1.amazonaws.com
docs.rinet.ru
dupont.free.fr
edusim.greenbush.us
dtek.chalmers.se
fifthgear.five.tv
friizu.pri.ee
fortune.cnn.com
grondziowski.neostrada.pl
iden.tify.us
fb.joyent.us
blog.tr.im
jspec.jaxa.jp
mashable.blogs.mu
lists.burri.to
com.edgesuite.net
my.noovo.us
blog.bit.ly
moon.dominos.jp

因此,对于上述所有子域,函数返回子域而不是域。 有人知道如何修复此功能吗?

【问题讨论】:

  • 该函数总是返回特定国家顶级域下的第三级域。它假设它们都是organization.type.country 的形式,例如oxford.ac.ukexample.co.cr.
  • @Barmar 你知道如何解决它吗? “compute-1.amazonaws.com”也是一些错误。 “dupont.free.fr”也应该是“free.fr”等。
  • 在不了解每个国家/地区的规则以及所有例外情况的情况下,我认为没有什么好的解决方案。

标签: php url dns


【解决方案1】:

试试:

function getDomain ($address) {

# Establishes Hostname
$uri[Hostname] = substr($address,0, (strpos($address,'.')));

# Establishes Domainname
$uri[Domainname] = substr($address, (strlen($uri[Hostname]) + 1));

if (preg_match("/\//", $uri[Domainname])) {
$uri[Domainname] = substr($uri[Domainname], 0, strpos($uri[Domainname],'/'));
}

# Establishes TLD
if (preg_match("/\./", $uri[Domainname])) {
$uri[TLD] = substr($uri[Domainname], (strpos($uri[Domainname],'.') + 1));
$uri[Domainname] = substr($uri[Domainname],0,-(strlen($uri[TLD]) + 1));
}

if (preg_match("/\//", $uri[TLD])) {
$uri[TLD] = substr($uri[TLD], 0, strpos($uri[TLD],'/'));
}

# Re-labels parts if there are only 2 (instead of 3)
if (count($uri) == 2) {
$uri[TLD] = $uri[Domainname];
$uri[Domainname] = $uri[Hostname];
unset ($uri[Hostname]);
}

# Added to handle domains of type .co.rs, .co.uk, .co.jp etc.
if ($uri[Domainname] == 'co') {
$uri[TLD] = $uri[Domainname].'.'.$uri[TLD];
$uri[Domainname] = $uri[Hostname];
unset ($uri[Hostname]);
}

return $uri;
}

此函数将采用任何标准网址(即不包括多个子域的网址)并返回一个包含主机名(可选)、域名和 TLD 的数组。

【讨论】:

  • 如果您还需要处理包含多个子域的网址,您可以将包含第二条和第三条if语句的块变成一个循环,从网址中提取每个子域。跨度>
  • 不起作用。对于域“slajer.co.rs”,它返回“Array ([Hostname] => slajer [Domainname] => co [TLD] => rs)”。但是 .co.rs 是顶级域名
  • 是的。我在末尾添加了一个块来处理 .co.rs、.co.uk、.co.jp 等 TLD。
【解决方案2】:

您可以使用简单的服务器功能轻松找到域名,如下所示...

     echo $_SERVER['SERVER_NAME'];

首先你可以像下面这样创建一个函数..

<?php

  function getDomain($url){
    if(filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED) === FALSE){
       return false;
     }

     /*** to get the url parts ***/
     $parts = parse_url($url);

     /*** return the host domain ***/
     return $parts['scheme'].'://'.$parts['host'];

   }
?>

然后像下面这样调用这个函数......

<?php

  $url = 'http://phpro.org/classes/Phproogle-Docs.html';
  echo getDomain($url);
?>

【讨论】:

  • 这绝对是一个有用的全局变量。但是...它不会从 URI 中提取域。
  • 现在希望它会返回确切的域...。如果不起作用,只需发送您期望的域格式作为示例...
猜你喜欢
  • 1970-01-01
  • 2014-04-28
  • 2011-03-27
  • 2010-09-22
  • 1970-01-01
  • 2011-01-10
  • 2015-07-14
  • 1970-01-01
相关资源
最近更新 更多