7

我正在过滤 $_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']) 会打扰我,因此“不雅”。

有没有优雅的方法?

4

1 回答 1

4

我认为您可以使用 mod_rewrite 或 apaches SetEnv 指令来解码 url 服务器端。这会改变 apache 中的 REQUEST_URI,从而改变 php.ini 中 $_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']);
于 2014-11-20T16:27:26.703 回答