我使用filter_var($url, FILTER_VALIDATE_URL)
找到的问题是它在$url = "http://x";
不需要TLD。我如何解决这个问题需要TLD?
答案 0 :(得分:1)
对于TLD验证,您需要使用Public Suffix List运行的库。以下是两种不同的解决方案。
首先是TLDDatabase,技术上它只是TLD的实际数据库。
$store = new LayerShifter\TLDDatabase\Store();
$store->isICCAN('com'); // returns true
$store->isICCAN('co.uk'); // returns true
$store->isICCAN('example'); // returns false
如果您需要更智能的解决方案,我建议TLDExtract。它可以用作验证器的域解析器。
$extract = new LayerShifter\TLDExtract\Extract();
$extract->setExtractionMode(Extract::MODE_ALLOW_ICCAN);
# For domain 'shop.github.com'
$result = $extract->parse('shop.github.com');
$result->getRegistrableDomain(); // will return 'github.com'
$result->getSuffix(); // will return 'com'
# For domain 'shop.github.co.uk'
$result = $extract->parse('http://shop.github.co.uk');
$result->getRegistrableDomain(); // will return 'github.co.uk'
$result->getSuffix(); // will return 'co.uk'
# For domain 'example.example'
$result = $extract->parse('https://example.example');
$result->getRegistrableDomain(); // will return NULL
$result->getSuffix(); // will return NULL
# For domain 'localhost'
$result = $extract->parse('localhost');
$result->getRegistrableDomain(); // will return NULL
$result->getSuffix(); // will return NULL
答案 1 :(得分:0)
根据RFC 3986中的官方URI规范,任何以方案开头的URI,例如http://
,并且在有效之后包含有效的URI字符:
每个URI都以第3.1节中定义的方案名称开头,该名称是指在该方案中分配标识符的规范。因此,URI语法是联合和可扩展的命名系统,其中每个方案的规范可以进一步限制使用该方案的标识符的语法和语义。
FILTER_VALIDATE_URL的作用是正确的。
http://localhost
或http://x
是完全有效的URI。
如果您确实要求并验证TLD,则必须使用包含所有有效TLD的白名单。因为每个TLD在子域,二级域等方面都有所不同。 有顶级域名,二级域名和子域名。从技术上讲,除TLD之外的所有内容都是子域名。
您可以在此处找到维护的TLD列表:
对于PHP实现(列表解析器):
从我的角度来看,这个问题不能通过" regexp"来解决。或"主机名扫描中的点数"。 一个例外:如果验证器的使用范围仅限于几个已知的URL,那么您可以使用这些策略解决此问题。
有趣的是此处建议的MX记录检查:https://stackoverflow.com/a/14688913/1163786
引用