filter_input()$ _SERVER [" REQUEST_URI"]与FILTER_SANITIZE_URL

时间:2014-06-26 13:09:23

标签: php global-variables filtering input-sanitization request-uri

我正在过滤$ _SERVER [“REQUEST_URI”],以便:

$_request_uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL);

php.net中所述:

  

FILTER_SANITIZE_URL

     

删除除字母,数字和字符之外的所有字符   $ -_ + *'(),{} | \ ^〜[]'<>#%“; /:!?@&安培; =

然而,

浏览器发送此REQUEST_URI值urlencode'd,因此在此filter_input()函数中未对其进行清理。说地址是

  

http://www.example.com/abc/index.php?q=abc 123

然后是已清理的请求网址

  

/abc/index.php?q=abc%EF%BF%BD%EF%BF%BD123

但它应该是

  

/abc/index.php?q=abc123

可能是urldecode($ _ SERVER [“REQUEST_URI”])然后使用filter_var()我们可以获得一个已清理的值。

$_request_uri = filter_var(urldecode($_SERVER['REQUEST_URI']), FILTER_SANITIZE_URL);

我不知道为什么最后一个在我看来“不优雅”而且我正在寻找一种优雅的方式,消毒$ _SERVER [“REQUEST_URI”]。

也许,在编码时直接访问超级全局数组($ _SERVER ['REQUEST_URI'])会让我感到不安,因此“不优雅”。

有优雅的方式吗?

1 个答案:

答案 0 :(得分:4)

我认为您可以使用mod_rewrite或apaches SetEnv指令来取消对url服务器端的编码。这会改变apache中的REQUEST_URI,从而改变php中$ _SERVER [" REQUEST_URI"]的值。

我不喜欢这个解决方案,你可能不想这样做。我看到的问题:

  • 它不允许多个get参数可能具有不同的验证规则。
  • 它允许任意参数。
  • 它需要用户可能没有的权限并更改默认服务器行为。
  • mod_rewrite很少是一个很好的解决方案。

避免全局的良好的解决方案是在INPUT_GET(而不是INPUT_SERVER)上调用filter_input或filter_input_array。

$urlParameters = http_build_query(
    filter_input_array(
        INPUT_GET,
        FILTER_SANITIZE_URL
    )
);

$_request_uri = filter_input(INPUT_SERVER, 'SCRIPT_URL', FILTER_SANITIZE_URL). ($urlParameters ? "?{$urlParameters}" : "");
print_r($_request_uri);

更好的解决方案是将特定参数列入白名单并使用特定规则进行验证,并直接使用这些参数(避免设置和解析$ _request_uri)

$_request_parameters = filter_input_array(
    INPUT_GET,
    array(
        'q' => FILTER_SANITIZE_URL,
    )
);

print_r($_request_parameters['q']);