这个主题在StackOverflow上已经讨论了很多,但我设法探索的所有答案都无法产生我需要的结果。我想在将URL插入数据库之前检查该值实际上是一个URL。即使我们只提供httpp:// exampl
,PHP FILTER_VALIDATE_URL的默认函数也会返回true但我需要验证该值,只有它是一个真正的域,如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 :(得分: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*)?@)?(?:(?!(?: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 :(得分:1)
http://example是一个有效的网址 - 如果您的本地网络上有一台名为example的计算机。
您想要的唯一解决方案(特别是考虑到有许多新的顶级域名)是连接并查看是否可以获得200 OK。
CURL可能是最好的解决方案。
这个superuser问题可能有助于从网址获取响应代码。
然而,你将无法获得100%的准确度