我需要构建一个函数,用于从URL中解析域名。
因此,使用
http://google.com/dhasjkdas/sadsdds/sdda/sdads.html
或者http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html
它应该返回google.com
使用
http://google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html
它应该返回google.co.uk
。
我需要构建一个函数,用于从URL中解析域名。
因此,使用
http://google.com/dhasjkdas/sadsdds/sdda/sdads.html
或者http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html
它应该返回google.com
使用
http://google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html
它应该返回google.co.uk
。
查看parse_url()
函数:
$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$parse = parse_url($url);
echo $parse['host']; // prints 'google.com'
parse_url
在处理非常糟糕的链接时表现不佳,但是对于一般性的链接则没有问题。
parse_url
不处理子域名,但 Purl 可以处理:https://github.com/jwage/purl - Damienparse_url()
可能会错误地解析包含破折号的域名的 URL。虽然没有确凿的证据,但请查看 此错误。FILTER_VALIDATE_URL
在内部使用 parse_url()
。 - XedinUnknown$parse
数组的其他内容,可以直接使用print parse_url($url, PHP_URL_HOST)
来输出解析出的URL主机部分。 - rybo111$domain = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST));
这将返回google.com
,适用于http://google.com/和http://www.google.com/
function getHost($Address) {
$parseUrl = parse_url(trim($Address));
return trim($parseUrl['host'] ? $parseUrl['host'] : array_shift(explode('/', $parseUrl['path'], 2)));
}
getHost("example.com"); // Gives example.com
getHost("http://example.com"); // Gives example.com
getHost("www.example.com"); // Gives www.example.com
getHost("http://example.com/xyz"); // Gives example.com
host
和 path
这样引用你的字符串。 - Gumbo!empty($parseUrl['host'])
。 - Demonslay335function get_domain($url = SITE_URL)
{
preg_match("/[a-z0-9\-]{1,63}\.[a-z\.]{2,6}$/", parse_url($url, PHP_URL_HOST), $_domain_tld);
return $_domain_tld[0];
}
get_domain('http://www.cdl.gr'); //cdl.gr
get_domain('http://cdl.gr'); //cdl.gr
get_domain('http://www2.cdl.gr'); //cdl.gr
原本应该百分之百正常运行的代码似乎对我并没有用处,我稍作修改示例,但发现有些代码不起作用且存在问题。因此,我将其更改为几个函数(以节省每次从Mozilla请求列表的时间,并移除缓存系统)。这已经在一组1000个URL上进行了测试,并且似乎可以正常工作。
function domain($url)
{
global $subtlds;
$slds = "";
$url = strtolower($url);
$host = parse_url('http://'.$url,PHP_URL_HOST);
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
foreach($subtlds as $sub){
if (preg_match('/\.'.preg_quote($sub).'$/', $host, $xyz)){
preg_match("/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/", $host, $matches);
}
}
return @$matches[0];
}
function get_tlds() {
$address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
$content = file($address);
foreach ($content as $num => $line) {
$line = trim($line);
if($line == '') continue;
if(@substr($line[0], 0, 2) == '/') continue;
$line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line);
if($line == '') continue; //$line = '.'.$line;
if(@$line[0] == '.') $line = substr($line, 1);
if(!strstr($line, '.')) continue;
$subtlds[] = $line;
//echo "{$num}: '{$line}'"; echo "<br>";
}
$subtlds = array_merge(array(
'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk',
'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au',
'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au'
), $subtlds);
$subtlds = array_unique($subtlds);
return $subtlds;
}
然后像这样使用它
$subtlds = get_tlds();
echo domain('www.example.com') //outputs: example.com
echo domain('www.example.uk.com') //outputs: example.uk.com
echo domain('www.example.fr') //outputs: example.fr
我知道应该将这个变成一个类,但是没有时间。
$url = 'http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$parse = parse_url($url);
echo $parse['host']; // prints 'www.google.com'
echo parse_url('https://subdomain.example.com/foo/bar', PHP_URL_HOST);
// Output: subdomain.example.com
echo parse_url('https://subdomain.example.co.uk/foo/bar', PHP_URL_HOST);
// Output: subdomain.example.co.uk
相反,您可以考虑这种务实的解决方案。 它将涵盖许多域名,但并非所有域名--例如,像'sos.state.oh.us'这样的较低级别域名未被涵盖。
function getDomain($url) {
$host = parse_url($url, PHP_URL_HOST);
if(filter_var($host,FILTER_VALIDATE_IP)) {
// IP address returned as domain
return $host; //* or replace with null if you don't want an IP back
}
$domain_array = explode(".", str_replace('www.', '', $host));
$count = count($domain_array);
if( $count>=3 && strlen($domain_array[$count-2])==2 ) {
// SLD (example.co.uk)
return implode('.', array_splice($domain_array, $count-3,3));
} else if( $count>=2 ) {
// TLD (example.com)
return implode('.', array_splice($domain_array, $count-2,2));
}
}
// Your domains
echo getDomain('http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'); // google.com
echo getDomain('http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html'); // google.com
echo getDomain('http://google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html'); // google.co.uk
// TLD
echo getDomain('https://shop.example.com'); // example.com
echo getDomain('https://foo.bar.example.com'); // example.com
echo getDomain('https://www.example.com'); // example.com
echo getDomain('https://example.com'); // example.com
// SLD
echo getDomain('https://more.news.bbc.co.uk'); // bbc.co.uk
echo getDomain('https://www.bbc.co.uk'); // bbc.co.uk
echo getDomain('https://bbc.co.uk'); // bbc.co.uk
// IP
echo getDomain('https://1.2.3.45'); // 1.2.3.45
最后,Jeremy Kendall的PHP Domain Parser可以帮助你从URL中解析出域名。另外,League URI Hostname Parser也可以完成这个工作。
http://google.com/dhasjkdas/sadsdds/sdda/sdads.html
,那么使用parse_url()是可行的解决方案。$extract = new LayerShifter\TLDExtract\Extract();
# For 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'
$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
parse_url($url, PHP_URL_HOST); // will return google.com
$result = $extract->parse($url);
$result->getFullHost(); // will return 'google.com'
$result->getRegistrableDomain(); // will return 'google.com'
$result->getSuffix(); // will return 'com'
# For 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html'
$url = 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html';
parse_url($url, PHP_URL_HOST); // will return 'search.google.com'
$result = $extract->parse($url);
$result->getFullHost(); // will return 'search.google.com'
$result->getRegistrableDomain(); // will return 'google.com'
我发现 @philfreo 的解决方案(引用自 php.net)在大部分情况下都能得到良好的结果,但有些情况下会显示 PHP 的 "notice" 和 "Strict Standards" 信息。这里是修正后的代码版本。
function getHost($url) {
$parseUrl = parse_url(trim($url));
if(isset($parseUrl['host']))
{
$host = $parseUrl['host'];
}
else
{
$path = explode('/', $parseUrl['path']);
$host = $path[0];
}
return trim($host);
}
echo getHost("http://example.com/anything.html"); // example.com
echo getHost("http://www.example.net/directory/post.php"); // www.example.net
echo getHost("https://example.co.uk"); // example.co.uk
echo getHost("www.example.net"); // example.net
echo getHost("subdomain.example.net/anything"); // subdomain.example.net
echo getHost("example.net"); // example.net
function getHost($url, $accept_www=false){
$URIs = parse_url(trim($url));
$host = !empty($URIs['host'])? $URIs['host'] : explode('/', $URIs['path'])[0];
return $accept_www == false? str_ireplace('www.', '', $host) : $host;
}
echo getHost("http://example.com/anything.html", 1).'<br>'; // example.com
echo getHost("http://www.example.net/directory/post.php", 1).'<br>'; // www.example.net
echo getHost("https://example.co.uk", 1).'<br>'; // example.co.uk
echo getHost("www.example.net", 1).'<br>'; // example.net
echo getHost("subdomain.example.net/anything", 1).'<br>'; // subdomain.example.net
echo getHost("http://blog.example.net/anything").'<br>'; // blog.example.net
echo getHost("example.net", 1).'<br>'; // example.net
echo '<br> ===== without "www" ===== <br><br>';
echo getHost("http://example.com/anything.html").'<br>'; // example.com
echo getHost("http://www.example.net/directory/post.php").'<br>'; // example.net
echo getHost("https://example.co.uk").'<br>'; // example.co.uk
echo getHost("www.example.net").'<br>'; // example.net
echo getHost("subdomain.example.net/anything").'<br>'; // subdomain.example.net
echo getHost("http://blog.example.net/anything").'<br>'; // blog.example.net
echo getHost("example.net").'<br>'; // example.net
$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$host = parse_url($url, PHP_URL_HOST);
print $host; // prints 'google.com'
这是我编写的代码,可以100%准确地找到域名,因为它考虑了mozilla子tlds。唯一需要检查的是如何缓存该文件,以避免每次都查询mozilla。
由于某些奇怪的原因,像co.uk这样的域名不在列表中,所以您需要进行一些hack并手动添加它们。这不是最干净的解决方案,但我希望能对某些人有所帮助。
//=====================================================
static function domain($url)
{
$slds = "";
$url = strtolower($url);
$address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
if(!$subtlds = @kohana::cache('subtlds', null, 60))
{
$content = file($address);
foreach($content as $num => $line)
{
$line = trim($line);
if($line == '') continue;
if(@substr($line[0], 0, 2) == '/') continue;
$line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line);
if($line == '') continue; //$line = '.'.$line;
if(@$line[0] == '.') $line = substr($line, 1);
if(!strstr($line, '.')) continue;
$subtlds[] = $line;
//echo "{$num}: '{$line}'"; echo "<br>";
}
$subtlds = array_merge(Array(
'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk',
'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au',
'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au',
),$subtlds);
$subtlds = array_unique($subtlds);
//echo var_dump($subtlds);
@kohana::cache('subtlds', $subtlds);
}
preg_match('/^(http:[\/]{2,})?([^\/]+)/i', $url, $matches);
//preg_match("/^(http:\/\/|https:\/\/|)[a-zA-Z-]([^\/]+)/i", $url, $matches);
$host = @$matches[2];
//echo var_dump($matches);
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
foreach($subtlds as $sub)
{
if (preg_match("/{$sub}$/", $host, $xyz))
preg_match("/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/", $host, $matches);
}
return @$matches[0];
}
co.uk
没有出现在列表中的原因是,该列表是顶级域名(TLD)的列表,而不是域名的列表。自从写下这个回答以来,ccTLD已经发生了很大变化。值得注意的是:"自2014年6月10日08:00 BST起,Nominet开始接受直接在.uk下进行的新注册。然而,对于已经拥有.co.uk、.org.uk、.me.uk、.net.uk、.ltd.uk或.plc.uk域名的现有客户,他们有一个预留期来申请相应的.uk域名,该预留期将持续到2019年6月10日的07:59 BST"。(来源) - ashleedawg
parse_url()
返回的是主机(host),而不是域名(domain)。 - MrWhiteparse_url
的限制而不是模糊的“我能做什么”。 - Lightness Races in Orbit