PHP filter_var URL

时间:2015-12-22 08:49:25

标签: php url filter-var

为了验证来自用户输入的URL路径,我正在使用PHP filter_var函数。 输入仅包含路径(/path/path/script.php)。

验证路径时,我添加了主机。我正在玩一点,测试输入验证等。这样做,我注意到过滤器URL函数的奇怪(??)行为。

代码:

$url = "http://www.domain.nl/http://www.google.nl/modules/authorize/test/normal.php";
var_dump(filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)); //valid

有人可以解释为什么这是一个有效的网址?谢谢!

1 个答案:

答案 0 :(得分:4)

简短的回答是,PHP FILTER_VALIDATE_URL仅根据RFC 2396检查URL,您的URL虽然很奇怪,但根据上述标准有效。

答案很长:

您使用的过滤器声明符合RFC,因此我们检查一下标准(RFC 2396)。

用于解析URL并在其中列出的正则表达式为:

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
 12            3  4          5       6  7        8 9

其中:

scheme    = $2
authority = $4
path      = $5
query     = $7
fragment  = $9

正如我们所看到的,“:”字符仅在方案的上下文中保留,从那时起“:”是公平的游戏(这由标准的文本支持)。例如,它在http:scheme中自由使用以表示端口。斜杠也可以出现在任何地方,并且没有任何东西禁止URL在中间某处有“//”。所以中间的“http://”应该是有效的。

让我们看看您的网址并尝试将其与此正则表达式匹配:

$url = "http://www.domain.nl/http://www.google.nl/modules/authorize/test/normal.php";
//Escaped a couple slashes to make things work, still the same regexp
$result_rfc = preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/',$url);
echo '<p>'.$result_rfc.'</p>';

测试返回'1',因此该url有效。这是可以预料的,因为规则没有声明中间有类似“http://”的网址无效,如我们所见。 PHP只是使用FILTER_VALIDATE_URL镜像此行为。

如果您想进行更严格的测试,则需要自己编写所需的代码。例如,您可以阻止“://”出现多次:

$url = "http://www.domain.nl/http://www.google.nl/modules/authorize/test/normal.php";
$result_rfc = preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/',$url);
if (substr_count($url,'://') != 1) {
    $result_non_rfc = false;
} else {
    $result_non_rfc = $result_rfc;
}

您也可以尝试调整正则表达式。