过滤掉input_get变量中的任何类型的URL,这是最好的方法吗?

时间:2014-12-05 12:17:04

标签: php

我已经提出了这个潜在的解决方案,但是想要仔细检查一下没有更好/更有效的方法。

如果?uri包含$ filter数组中的任何内容,它应该退出。注意:我想检查不包含网址,例如?url = http://google.com,因此例如FILTER_VALIDATE_URL无效。

使用我的uri,我只想接受以下参数:'example'或'example-example',因为uri已经附加到具有域的变量上。因此,示例输出将是domain.com/pdf.php?uri=example-example

    $uri = filter_input(INPUT_GET, 'uri', FILTER_SANITIZE_STRING);
    $filter = array('http://', 'https://' ,'www.', '.', '@', '/');

    foreach ($filter as $k) {
        if (strpos($uri, $k) === false) {
            // No matches, carry on
        } else {
            // Match is found, exit
            exit("Error in url parameter: $k is not allowed!");
        }
    }

3 个答案:

答案 0 :(得分:2)

您可以定义自己的自定义过滤器:

$uri = filter_input(INPUT_GET, 'uri', FILTER_CALLBACK, [
    'options' => function($value) {
        return !preg_match('~https?://|[.@/]~', $value);
    }
]);

答案 1 :(得分:1)

有几种方法可以做到这一点。

据我所知,您不希望它包含任何URI方案或字符,例如@或/或www。

您可以使用正则表达式仅允许您需要的字符:

// not valid
$uri = 'http://google.com';

// Is only valid if contains A-Z, a-z, 0-9, -, _
$isValidUri = preg_match('/^[\-A-Za-z0-9_]+$/', $uri);

if ($isValidUri) {
    // Do something here with the valid uri . . .
} else throw new Exception('Not a valid uri');

您也可以使用PHP filter_inputfilter_var函数来清理输入。但要非常仔细消毒用户输入并确保彻底测试以防止滥用。

答案 2 :(得分:0)

无论挑战如何,PHP通常会为同一解决方案提供不同的路径。关键是要确定哪个最适合您的特定目的。有时任何有效的代码都是最好的解决方案。其他时候,例如,您可能需要测试各种解决方案,以查看哪一个最快。

所以,你问是否有“更好或更有效的方式”。 “更好”是主观的;通过测试可以确定更高效。例如,针对现有代码测试下面的代码,看看哪个版本执行得更快。通过这样做,您将学习如何制定自己的“哪个是最好的”决策,而不是依赖他人的意见。这样做有助于您成为一名受过良好教育的程序员。

$start = microtime(true);
$myarray = array("http://google.com","ftp://google.com","https://google.com","Nothing to see here");
foreach ($myarray as $uri)
{
if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$uri)) 

{
  echo "$uri contains no matches - carry on<br>";
} else {
          echo "Match is found in $uri, <br>";
       }
}
$elapsed_time = (microtime(true) - $start);
echo "Routine took $elapsed_time seconds to run";