2015-10-03 36 views
1

在StackOverflow中已经讨论了很多主题,但是我设法探索的所有答案都无法产生我需要的结果。我想在将URL插入数据库之前检查该值实际上是否为URL。 PHP FILTER_VALIDATE_URL的默认函数返回true,即使我们只提供httpp://例子PHP中的URL验证

但我需要验证该值只有当它是一个真正的域名,如example.net,example.com等。让我们尝试一个例如:

案例1:

$url = "http://example"; 
if(!filter_var($url, FILTER_VALIDATE_URL) === false) { 
       return true; 
      } 

这上面返回true,但域是无效的。

案例2:

$url = "http://google.com"; 
if(!filter_var($url, FILTER_VALIDATE_URL) === false) { 
       return true; 
      } 

返回true,那也没关系。

但情况1的任何可能的解决方案?请帮忙。

P.S .:我使用CURL,它的工作原理但响应速度太慢(超过5秒)。任何固体解决方案将不胜感激。

+0

什么是真正的* *域?我不知道你认为什么是有效的 –

+0

Will [get_headers](http://it.php.net/manual/en/function.get-headers.php)有帮助吗? – SearchAndResQ

+0

感谢@Dagon,感谢您的回应。对不起,我在这个问题上的拼写错误。我编辑过它。我的意思是http://示例不能是有效的域,因为它缺少TLD(.com,.net等),但该函数将其视为有效的域。我希望我让你明确我的问题。 – Rehmat

回答

3

我编写了一个快速脚本,可以帮助你实现你需要的东西:

<?php 
//error_reporting(E_ALL); 
//ini_set('display_errors', 1); 
$url = "http://www.google.com"; 


if(validateUrl($url)){ 
    echo "VALID"; 
}else{ 
    echo "INVALID"; 
} 

function validateUrl($url){ 

//first we validate the url using a regex 

if (!preg_match('%^(?:(?:https?)://)(?:\S+(?::\S*)[email protected])?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]-*)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$%uiS', $url)) { 

    return false; 
} 


//if the url is valid, we "curl it" and expect to get a 200 header response in order to validate it. 

$ch = curl_init($url); 
curl_setopt($ch, CURLOPT_HEADER, true); // we want headers 
curl_setopt($ch, CURLOPT_NOBODY, true); // we don't need body (faster) 
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1); // we follow redirections 
curl_setopt($ch, CURLOPT_TIMEOUT,10); 
$output = curl_exec($ch); 
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 
curl_close($ch); 


if($httpcode == "200"){ 
    return true; 
}else{ 
    return false; 
} 


} 
+1

谢谢,没有取得身体,反应更快。我会坚持下去,除非我找到比这更快的东西:) – Rehmat

+0

不客气,很高兴它解决了。 –

1

http://example是一个有效的网址 - 如果您的计算机在本地网络上被称为示例。

你想要什么(特别是考虑到有很多新的顶级域名)唯一的解决方案是连接并看看你是否得到200 OK。

CURL可能是这里最好的解决方案。

superuser这个问题可能有助于从url获取响应代码。

然而,你将永远不会得到100%的准确率