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

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

在我的例子中,许多网站建议的实际查询字符串(使用 CURL 或 file_get_contents()函数)的解决方案是不可能的,我想避免它。

我考虑了正则表达式或其他解决方案。

275555 次浏览

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

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');
}
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;
}
}

你可以使用这个函数,但是如果网站脱机,它将返回 false。

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

下面是我找到的最好的教程:

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")

另一种检查给定的 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
)*/
}

对于带有非 ascii 字符的 url,使用 filter _ var ()将会失败,例如(http://pt.wikipedia.org/wiki/Guimarães)。下面的函数在调用 filter _ var ()之前对所有非 ascii 字符(例如 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";
}

就个人而言,我想在这里使用正则表达式。

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

鉴于 filter _ var ()需要 http://的问题,我使用:

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

我在2012年看到了 这篇文章,它考虑到了变量 可能或不可能只是普通的 URL。

本文的作者 David Müeller提供了这个函数,他说,“ ... ... 可能值得使用(原文如此)”,同时还提供了 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
);
}

实际上... FILTER _ var ($url,FILTER _ VALIDATE _ URL) ; 工作得不是很好。 当你输入一个真正的网址,它工作,但它只检查 http:// 所以如果你输入类似“ http://weirtgcyaurbatc”的东西,它仍然会说它是真实的。

如果有人有兴趣使用 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;
}
public function testing($Url=''){
$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;
}