php 如何在PHP中验证域名?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1755144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:42:32  来源:igfitidea点击:

How to validate domain name in PHP?

phpregexdomain-name

提问by Richard Knop

Is it possible without using regular expression?

不使用正则表达式可以吗?

For example, I want to check that a string is a valid domain:

例如,我想检查一个字符串是否是一个有效的域:

domain-name
abcd
example

Are valid domains. These are invalid of course:

是有效的域。这些当然是无效的:

domaia@name
ab$%cd

And so on. So basically it should start with an alphanumeric character, then there may be more alnum characters plus also a hyphen. And it must end with an alnum character, too.

等等。所以基本上它应该以字母数字字符开头,然后可能会有更多的alnum字符加上一个连字符。它也必须以 anum 字符结尾。

If it's not possible, could you suggest me a regexp pattern to do this?

如果不可能,你能建议我一个正则表达式模式来做到这一点吗?

EDIT:

编辑:

Why doesn't this work? Am I using preg_match incorrectly?

为什么这不起作用?我是否错误地使用了 preg_match?

$domain = '@djkal';
$regexp = '/^[a-zA-Z0-9][a-zA-Z0-9\-\_]+[a-zA-Z0-9]$/';
if (false === preg_match($regexp, $domain)) {
    throw new Exception('Domain invalid');
}

回答by velcrow

<?php
function is_valid_domain_name($domain_name)
{
    return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name) //valid chars check
            && preg_match("/^.{1,253}$/", $domain_name) //overall length check
            && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name)   ); //length of each label
}
?>

Test cases:

测试用例:

is_valid_domain_name? [a]                       Y
is_valid_domain_name? [0]                       Y
is_valid_domain_name? [a.b]                     Y
is_valid_domain_name? [localhost]               Y
is_valid_domain_name? [google.com]              Y
is_valid_domain_name? [news.google.co.uk]       Y
is_valid_domain_name? [xn--fsqu00a.xn--0zwm56d] Y
is_valid_domain_name? [goo gle.com]             N
is_valid_domain_name? [google..com]             N
is_valid_domain_name? [google.com ]             N
is_valid_domain_name? [google-.com]             N
is_valid_domain_name? [.google.com]             N
is_valid_domain_name? [<script]                 N
is_valid_domain_name? [alert(]                  N
is_valid_domain_name? [.]                       N
is_valid_domain_name? [..]                      N
is_valid_domain_name? [ ]                       N
is_valid_domain_name? [-]                       N
is_valid_domain_name? []                        N

回答by RoboTamer

With this you will not only be checking if the domain has a valid format, but also if it is active / has an IP address assigned to it.

有了这个,您不仅要检查域是否具有有效格式,还要检查它是否处于活动状态/是否分配了 IP 地址。

$domain = "stackoverflow.com";

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

Note that this method requires the DNS entries to be active so if you require a domain string to be validated without being in the DNS use the regular expression method given by velcrow above.

请注意,此方法要求 DNS 条目处于活动状态,因此如果您需要在不在 DNS 中的情况下验证域字符串,请使用上面由 velcrow 提供的正则表达式方法。

Also this function is not intended to validate a URL string use FILTER_VALIDATE_URL for that. We do not use FILTER_VALIDATE_URL for a domain because a domain string is not a valid URL.

此外,此函数不用于验证 URL 字符串,为此使用 FILTER_VALIDATE_URL。我们不对域使用 FILTER_VALIDATE_URL,因为域字符串不是有效的 URL。

回答by Rob

PHP 7

PHP 7

// Validate a domain name
var_dump(filter_var('mandrill._domainkey.mailchimp.com', FILTER_VALIDATE_DOMAIN));
# string(33) "mandrill._domainkey.mailchimp.com"

// Validate an hostname (here, the underscore is invalid)
var_dump(filter_var('mandrill._domainkey.mailchimp.com', FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME));
# bool(false)

It is not documented here: http://www.php.net/filter.filters.validateand a bug request for this is located here: https://bugs.php.net/bug.php?id=72013

此处未记录:http://www.php.net/filter.filters.validate此错误请求位于此处:https://bugs.php.net/bug.php?id=72013

回答by Hymantrade

use checkdnsrrhttp://php.net/manual/en/function.checkdnsrr.php

使用checkdnsrr http://php.net/manual/en/function.checkdnsrr.php

$domain = "stackoverflow.com";

checkdnsrr($domain , "A");

//returns true if has a dns A record, false otherwise

回答by Alnitak

Firstly, you should clarify whether you mean:

首先,您应该澄清您的意思是:

  1. individual domain name labels
  2. entire domain names (i.e. multiple dot-separate labels)
  3. host names
  1. 个人域名标签
  2. 整个域名(即多个点分隔标签)
  3. 主机名

The reason the distinction is necessary is that a label can technically include anycharacters, including the NUL, @and '.' characters. DNS is 8-bit capable and it's perfectly possible to have a zone file containing an entry reading "an\0odd\.l@bel". It's not recommended of course, not least because people would have difficulty telling a dot inside a label from those separating labels, but it islegal.

之所以有必要进行区分,是因为标签在技术上可以包含任何字符,包括 NUL@和 ' .' 字符。DNS 支持 8 位,并且完全有可能拥有一个包含条目为“ an\0odd\.l@bel”的区域文件。当然不推荐这样做,尤其是因为人们很难从那些分隔标签中分辨出标签内的点,但这合法的。

However, URLsrequire a hostname in them, and those are governed by RFCs 952 and 1123. Valid hostnames are a subset of domainnames. Specifically only letters, digits and hyphen are allowed. Furthermore the first and last characters cannot be a hyphen. RFC 952 didn't permit a number for the first character, but RFC 1123 subsequently relaxed that.

但是,URL需要在其中包含主机名,并且这些受 RFC 952 和 1123 的约束。有效的主机名是域名的子集。具体来说,只允许使用字母、数字和连字符。此外,第一个和最后一个字符不能是连字符。RFC 952 不允许第一个字符使用数字,但 RFC 1123 随后放宽了这一点。

Hence:

因此:

  • a- valid
  • 0- valid
  • a-- invalid
  • a-b- valid
  • xn--dasdkhfsd- valid (punycode encoding of an IDN)
  • a- 有效的
  • 0- 有效的
  • a-- 无效的
  • a-b- 有效的
  • xn--dasdkhfsd- 有效(IDN 的punycode 编码)

Off the top of my head I don't think it's possible to invalidate the a-example with a single simple regexp. The best I can come up with to check a singlehostlabel is:

在我的脑海中,我认为不可能a-用一个简单的正则表达式使示例无效。我能想出的最好的检查单个主机标签是:

if (preg_match('/^[a-z\d][a-z\d-]{0,62}$/i', $label) &&
   !preg_match('/-$/', $label))
{
    # label is legal within a hostname
}

To further complicate matters, some domain name entries (typically SRVrecords) use labels prefixed with an underscore, e.g. _sip._udp.example.com. These are nothost names, but are legal domain names.

更复杂的是,一些域名条目(通常是SRV记录)使用带有下划线前缀的标签,例如_sip._udp.example.com. 这些不是主机名,而是合法的域名。

回答by Cups

I think once you have isolated the domain name, say, using Erklan's idea:

我想一旦你隔离了域名,比如说,使用 Erklan 的想法:

$myUrl = "http://www.domain.com/link.php";
$myParsedURL = parse_url($myUrl);
$myDomainName= $myParsedURL['host'];

you could use :

你可以使用:

if( false === filter_var( $myDomainName, FILTER_VALIDATE_URL ) ) {
// failed test

}

PHP5s Filter functions are for just such a purpose I would have thought.

PHP5 的过滤器函数就是为了这个目的,我会想到。

It does not strictly answer your question as it does not use Regex, I realise.

我意识到它没有严格回答您的问题,因为它不使用正则表达式。

回答by Erkan BALABAN

Here is another way without regex.

这是没有正则表达式的另一种方式。

$myUrl = "http://www.domain.com/link.php";
$myParsedURL = parse_url($myUrl);
$myDomainName= $myParsedURL['host'];
$ipAddress = gethostbyname($myDomainName);
if($ipAddress == $myDomainName)
{
   echo "There is no url";
}
else
{
   echo "url found";
}

回答by James Brooks

Regular expression is the most effective way of checking for a domain validation. If you're dead set on not using a Regular Expression (which IMO is stupid), then you could split each part of a domain:

正则表达式是检查域验证的最有效方法。如果您坚决不使用正则表达式(IMO 很愚蠢),那么您可以拆分域的每个部分:

  • www. / sub-domain
  • domain name
  • .extension
  • 万维网。/ 子域
  • 域名
  • 。延期

You would then have to check each character in some sort of a loop to see that it matches a valid domain.

然后,您必须检查某种循环中的每个字符,以查看它是否与有效域匹配。

Like I said, it's much more effective to use a regular expression.

就像我说的,使用正则表达式要有效得多。

回答by Arthur Reutenauer

Your regular expression is fine, but you're not using preg_matchright. It returns an int(0 or 1), not a boolean. Just write if(!preg_match($regex, $string)) { ... }

你的正则表达式很好,但你没有preg_match正确使用。它返回一个int(0 或 1),而不是一个布尔值。写就好了if(!preg_match($regex, $string)) { ... }

回答by Matteo Riva

If you don't want to use regular expressions, you can try this:

如果你不想使用正则表达式,你可以试试这个:

$str = 'domain-name';

if (ctype_alnum(str_replace('-', '', $str)) && $str[0] != '-' && $str[strlen($str) - 1] != '-') {
    echo "Valid domain\n";
} else {
    echo "Invalid domain\n";
}

but as said regexp are the best tool for this.

但正如所说的正则表达式是最好的工具。