检查URL是否有效的最佳方法


148

我想使用PHP来检查字符串是否存储在 $myoutput变量中的包含有效的链接语法,或者仅仅是普通文本。我正在寻找的功能或解决方案应该能够识别所有链接格式,包括带有GET参数的链接格式。

file_get_contents()在我的情况下,在许多站点上建议的一种实际查询字符串(使用CURL或函数)的解决方案是不可能的,我希望避免这种情况。

我想到了正则表达式或其他解决方案。


使用CURL或获取它的HTTP内容可能会很慢,如果您想要更快,更可靠的东西,请考虑在主机名上使用gethostbyaddr()。如果它解析为IP,则可能有一个网站。当然这取决于您的需求。
TravisO 2010年

Answers:


300

您可以使用本地过滤器验证器

filter_var($url, FILTER_VALIDATE_URL);

验证值是否为URL(根据» http://www.faqs.org/rfcs/rfc2396),并可选地使用必需的组件。当心有效的URL可能未指定HTTP协议http://,因此可能需要进一步的验证才能确定URL使用预期的协议,例如ssh://或mailto:。请注意,该函数只会找到有效的ASCII URL。国际化域名(包含非ASCII字符)将失败。

例:

if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
    die('Not a valid URL');
}

9
@Raveren预期的行为,因为这些是有效的URL。
戈登

8
请注意,FILTER_VALIDATE_URL这不会验证url的协议。因此ssh://ftp://等会通过。
Seph 2014年

3
@SephVelut的预期行为,因为这些是有效的URL。
戈登2014年

1
它允许类似ttp://amazon.com的网址
Elia Weiss

3
@JoshHabdas,我认为您错过了重点。PHP代码完全按照其声明的方式工作。但这看不懂你的想法。无效和不需要之间有巨大的区别。不需要是非常主观的,这就是为什么它留给程序员来解决这个细节的原因。您可能还会注意到该代码验证了URL,但没有证明它存在。用户输入可以验证的“ amazon”,“ amozon”并不是错误的PHP,但这仍然是不希望的。
JBH

20

这是我在那找到的最好的教程:

http://www.w3schools.com/php/filter_validate_url.asp

<?php
$url = "http://www.qbaki.com";

// Remove all illegal characters from a url
$url = filter_var($url, FILTER_SANITIZE_URL);

// Validate url
if (filter_var($url, FILTER_VALIDATE_URL) !== false) {
echo("$url is a valid URL");
} else {
echo("$url is not a valid URL");
}
?>

可能的标志:

FILTER_FLAG_SCHEME_REQUIRED - URL must be RFC compliant (like http://example)
FILTER_FLAG_HOST_REQUIRED - URL must include host name (like http://www.example.com)
FILTER_FLAG_PATH_REQUIRED - URL must have a path after the domain name (like www.example.com/example1/)
FILTER_FLAG_QUERY_REQUIRED - URL must have a query string (like "example.php?name=Peter&age=37")

1
只是一个尼特:!filter_var(...) === false==> filter_var(...) === truefilter_var(...)。:)
Domenico De Felice

@ErichGarcía此代码不会像OP要求的那样检查它是否是有效的HTTP / S URL。这将传递诸如ssh://,ftp://之类的信息,这只会根据RFC 2396检查其语法上是否有效
twigg

不要使用FILTER_VALIDATE_URL。这是混乱且不可靠的。例如,它确认ttps://www.youtube.com为有效
Jeffz

12

对于带有非ASCII字符的网址,使用filter_var()将失败,例如(http://pt.wikipedia.org/wiki/Guimarães)。以下函数在调用filter_var()之前对所有非A​​SCII字符(例如http://pt.wikipedia.org/wiki/Guimar%C3%A3es)进行编码。

希望这对某人有帮助。

<?php

function validate_url($url) {
    $path = parse_url($url, PHP_URL_PATH);
    $encoded_path = array_map('urlencode', explode('/', $path));
    $url = str_replace($path, implode('/', $encoded_path), $url);

    return filter_var($url, FILTER_VALIDATE_URL) ? true : false;
}

// example
if(!validate_url("http://somedomain.com/some/path/file1.jpg")) {
    echo "NOT A URL";
}
else {
    echo "IS A URL";
}

就是这个。终于有人在2017
Kyle KIM,

为我工作(其他人没有顺便说一句):)
乔诺(Jono)

这是唯一为我工作的解决方案。谢谢!
西拉斯,

10
function is_url($uri){
    if(preg_match( '/^(http|https):\\/\\/[a-z0-9_]+([\\-\\.]{1}[a-z_0-9]+)*\\.[_a-z]{2,5}'.'((:[0-9]{1,5})?\\/.*)?$/i' ,$uri)){
      return $uri;
    }
    else{
        return false;
    }
}

3

我个人想在这里使用正则表达式。贝娄代码非常适合我。

$baseUrl     = url('/'); // for my case https://www.xrepeater.com
$posted_url  = "home";
// Test with one by one
/*$posted_url  = "/home";
$posted_url  = "xrepeater.com";
$posted_url  = "www.xrepeater.com";
$posted_url  = "http://www.xrepeater.com";
$posted_url  = "https://www.xrepeater.com";
$posted_url  = "https://xrepeater.com/services";
$posted_url  = "xrepeater.dev/home/test";
$posted_url  = "home/test";*/

$regularExpression  = "((https?|ftp)\:\/\/)?"; // SCHEME Check
$regularExpression .= "([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?"; // User and Pass Check
$regularExpression .= "([a-z0-9-.]*)\.([a-z]{2,3})"; // Host or IP Check
$regularExpression .= "(\:[0-9]{2,5})?"; // Port Check
$regularExpression .= "(\/([a-z0-9+\$_-]\.?)+)*\/?"; // Path Check
$regularExpression .= "(\?[a-z+&\$_.-][a-z0-9;:@&%=+\/\$_.-]*)?"; // GET Query String Check
$regularExpression .= "(#[a-z_.-][a-z0-9+\$_.-]*)?"; // Anchor Check

if(preg_match("/^$regularExpression$/i", $posted_url)) { 
    if(preg_match("@^http|https://@i",$posted_url)) {
        $final_url = preg_replace("@(http://)+@i",'http://',$posted_url);
        // return "*** - ***Match : ".$final_url;
    }
    else { 
          $final_url = 'http://'.$posted_url;
          // return "*** / ***Match : ".$final_url;
         }
    }
else {
     if (substr($posted_url, 0, 1) === '/') { 
         // return "*** / ***Not Match :".$final_url."<br>".$baseUrl.$posted_url;
         $final_url = $baseUrl.$posted_url;
     }
     else { 
         // return "*** - ***Not Match :".$posted_url."<br>".$baseUrl."/".$posted_url;
         $final_url = $baseUrl."/".$final_url; }
}

1
这是验证网站URL的最佳答案。只需进行少量更改,即可完美完成。谢谢
阿米尔·侯赛因·卡里米

3

给定filter_var()需要http://的问题,我使用:

$is_url = filter_var($filename, FILTER_VALIDATE_URL) || array_key_exists('scheme', parse_url($filename));


不要使用FILTER_VALIDATE_URL。这是混乱且不可靠的。例如,它验证ttps://www.youtube.com为有效
Jeffz,

2

您可以使用此功能,但如果网站离线,它将返回false。

  function isValidUrl($url) {
    $url = parse_url($url);
    if (!isset($url["host"])) return false;
    return !(gethostbyname($url["host"]) == $url["host"]);
}


1

检查给定URL是否有效的另一种方法是尝试访问它,下面的函数将从给定URL获取标头,这将确保URL有效并且 Web服务器处于活动状态:

function is_url($url){
        $response = array();
        //Check if URL is empty
        if(!empty($url)) {
            $response = get_headers($url);
        }
        return (bool)in_array("HTTP/1.1 200 OK", $response, true);
/*Array
(
    [0] => HTTP/1.1 200 OK 
    [Date] => Sat, 29 May 2004 12:28:14 GMT
    [Server] => Apache/1.3.27 (Unix)  (Red-Hat/Linux)
    [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT
    [ETag] => "3f80f-1b6-3e1cb03b"
    [Accept-Ranges] => bytes
    [Content-Length] => 438
    [Connection] => close
    [Content-Type] => text/html
)*/ 
    }   

好主意。如果服务器使用HTTP / 1.0或HTTP / 2.0,则此操作将失败,或返回重定向。
iblamefish '17

是的,这是一个起点,可以轻松完成进一步的改进。
巴德·达米扬诺夫

1

从2012年开始出现在本文中。它考虑了可能会或可能不会的变量纯URL的。

文章的作者DavidMüeller提供了此功能,他说:“ ...值得一提,[sic]”,以及一些示例filter_var及其缺点。

/**
 * Modified version of `filter_var`.
 *
 * @param  mixed $url Could be a URL or possibly much more.
 * @return bool
 */
function validate_url( $url ) {
    $url = trim( $url );

    return (
        ( strpos( $url, 'http://' ) === 0 || strpos( $url, 'https://' ) === 0 ) &&
        filter_var(
            $url,
            FILTER_VALIDATE_URL,
            FILTER_FLAG_SCHEME_REQUIRED || FILTER_FLAG_HOST_REQUIRED
        ) !== false
    );
}

0

如果有人有兴趣使用cURL进行验证。您可以使用以下代码。

<?php 
public function validationUrl($Url){
        if ($Url == NULL){
            return $false;
        }
        $ch = curl_init($Url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $data = curl_exec($ch);
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return ($httpcode >= 200 && $httpcode < 300) ? true : false; 
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.