PHP中的URL验证


URL Validation in PHP

这个话题在StackOverflow上已经讨论了很多,但是我设法探索的所有答案都没有产生我需要的结果。在将URL插入数据库之前,我想检查该值实际上是一个URL。PHP的默认函数FILTER_VALIDATE_URL返回true,即使我们只提供http://example

,但我需要验证值只有当它是一个真正的域,如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有什么可能的解决方案吗?请帮助。

注::我使用CURL,它工作,但响应太慢(超过5秒)。

我已经编写了一个快速脚本,可以帮助您实现所需的内容:

<?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;
}

}

http://example是一个有效的url -如果您在本地网络上有一台名为example的计算机。

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

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

这个超级用户问题可能有助于从url中获取响应代码。

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