PHP – 过滤器(filters)


在 PHP 应用程序中进行处理之前,必须验证以客户端请求形式接收的输入数据,这一点很重要。为了执行输入验证,PHP 中的 filter 扩展提供了许多 filter 函数,由预定义 filter 常量和标志支持。PHP 库的过滤器扩展还有助于清理 GET POST 方法接收的输入。

过滤器(filter)扩展是一项强大的功能,有助于防止安全漏洞,例如 SQL 注入和跨站点脚本。该扩展具有两种类型的过滤器 -

验证过滤器

验证筛选器检查数据是否满足特定条件。例如,您希望确保用户在 HTML 表单中正确输入了电子邮件字段。FILTER_VALIDATE_EMAIL 将确定数据是否为有效的电子邮件地址。但是,验证筛选器不会更改数据本身。

清理过滤器

清理是指从输入中删除不需要的字符的过程。因此,它可能会通过删除不需要的字符来更改数据。例如,传入 FILTER_SANITIZE_EMAIL 将删除不适合电子邮件地址包含的字符,而不执行验证。

过滤器标志

PHP 的 filter 扩展定义了许多 filter 标志,如下所示 -

ID 描述
FILTER_FLAG_STRIP_LOW 去除数值为 <32 的字符。
FILTER_FLAG_STRIP_HIGH 去除数值为 >127 的字符。
FILTER_FLAG_STRIP_BACKTICK 去除反引号字符。
FILTER_FLAG_ALLOW_FRACTION 允许句点 (.) 作为数字中的小数分隔符。
FILTER_FLAG_ALLOW_THOUSAND 允许使用逗号 (,) 作为数字中的千位分隔符。
FILTER_FLAG_ALLOW_SCIENTIFIC 允许使用 e 或 E 表示数字中的科学记数法。
FILTER_FLAG_NO_ENCODE_QUOTES 如果存在此标志,则不会对单引号 (') 和双引号 (“) 进行编码。
FILTER_FLAG_ENCODE_LOW 使用数值 <32 对所有字符进行编码。
FILTER_FLAG_ENCODE_HIGH 使用数值 >127 对所有字符进行编码。
FILTER_FLAG_ENCODE_AMP 对 & 符号 (&) 进行编码。
FILTER_NULL_ON_FAILURE 对于无法识别的值,返回 null
FILTER_FLAG_ALLOW_OCTAL 将以零 (0) 开头的输入视为八进制数。
FILTER_FLAG_ALLOW_HEX 将以 0x 或 0X 开头的输入视为十六进制数。
FILTER_FLAG_EMAIL_UNICODE 允许电子邮件地址的本地部分包含 Unicode 字符。
FILTER_FLAG_IPV4 允许 IP 地址采用 IPv4 格式。
FILTER_FLAG_IPV6 允许 IP 地址采用 IPv6 格式。
FILTER_FLAG_NO_PRIV_RANGE 以下私有 IPv4 范围的验证失败:10.0.0.0/8、172.16.0.0/12 和 192.168.0.0/16。
FILTER_FLAG_NO_RES_RANGE 以下保留 IPv4 范围验证失败:0.0.0.0/8、169.254.0.0/16、127.0.0.0/8 和 240.0.0.0/4。
以下保留 IPv6 范围验证失败::1/128、::/128、::ffff:0:0/96 和 fe80::/10。
FILTER_FLAG_GLOBAL_RANGE 未通过非全局 IPv4/IPv6 范围的验证
FILTER_FLAG_SCHEME_REQUIRED 要求 URL 包含 scheme 部分。
FILTER_FLAG_HOST_REQUIRED 要求 URL 包含主机部件。
FILTER_FLAG_PATH_REQUIRED 要求 URL 包含路径部分。
FILTER_FLAG_QUERY_REQUIRED 要求 URL 包含查询字符串。
FILTER_REQUIRE_SCALAR 要求值为 scalar。
FILTER_REQUIRE_ARRAY 要求值为数组。
FILTER_FORCE_ARRAY 如果值是标量,则将其视为数组,标量值仅作为元素。
   

Filter 函数

过滤器扩展包括以下过滤器功能 -

ID 描述
filter_has_var() 检查是否存在指定类型的变量
filter_id() 返回属于命名过滤器的过滤器 ID
filter_input_array() 获取外部变量并选择性地过滤它们
filter_input() 按名称获取特定的外部变量并对其进行筛选
filter_list() 返回所有支持的筛选器的列表
filter_var_array() 获取多个变量并选择性地过滤它们
filter_var() 使用指定的过滤器过滤变量

预定义常量

上述函数使用一个名为 input_type 的参数,它是预定义的枚举常量之一,表示如何将输入提供给 PHP 脚本以进行过滤。

常量 类型
INPUT_POST (int) POST 变量
INPUT_GET (int) GET 变量
INPUT_COOKIE (int) COOKIE 变量
INPUT_ENV (int) ENV 变量
INPUT_SERVER (int) SERVER 变量
INPUT_SESSION (int) SESSION 变量
INPUT_REQUEST (int) REQUEST 变量

filter_has_var() 函数

filter_has_var() 函数检查是否存在指定类型的变量。


 filter_has_var(int $input_type, string $var_name): bool

input_type 是预定义的常量之一 INPUT_GETINPUT_POSTINPUT_COOKIEINPUT_SERVERINPUT_ENV;其中,var_name 参数是要检查的变量的名称。该函数在成功时返回 true,在失败时返回 false

例子

在 XAMPP 服务器上访问以下 PHP 脚本。


<?php
   if (!filter_has_var(INPUT_GET, "email")) {
      echo("Email not found");
   } else {
      echo("Email found");
   }
?>

它将产生以下输出 -

访问 http://localhost/hello.php?email=abc@example.com

Email found

filter_input() 函数

filter_input() 函数按名称获取特定的外部变量,并根据应用的过滤器常量对其进行过滤


filter_input(
   int $type,
   string $var_name,
   int $filter = FILTER_DEFAULT,
   array|int $options = 0
): mixed

类型参数是常量 INPUT_GETINPUT_POSTINPUT_COOKIEINPUT_SERVER INPUT_ENV 之一。第二个参数是 var_name,即要获取的变量的名称。您可以使用要应用的过滤器。使用任何预定义的筛选器标志。如果省略,将使用 FILTER_DEFAULT

该函数在成功时返回所请求变量的值,如果过滤器失败则返回 false,如果未设置 var_name 变量,则返回 null

例子

请看下面的例子 -


<?php
   if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL)) {
      echo("Email is not valid");
   } else {
      echo("Email is valid");
   }
?>

它将产生以下输出 -

如果您使用 URL http://localhost/hello.php?email=abc@example.com,

Email is valid

如果 URL 为 http://localhost/hello.php?email=a b c@example.com

Email is not valid

您还可以使用 INPUT_POST 类型来验证通过 POST 方法接收的输入 -


<?php
   if (!filter_input(INPUT_POST, "email", FILTER_VALIDATE_EMAIL)) {
      echo("Email is not valid");
   } else {
      echo("Email is valid");
   }
?>

要使用 POST 请求传递数据,请打开命令提示符,然后使用以下 CURL 命令

curl -X POST -d "{\"email\": \"a@b.com\"}" http://localhost/hello.php

filter_list() 函数

filter_list() 函数返回所有受支持过滤器的列表


 filter_list(): array

例子

该函数返回所有受支持过滤器的名称数组,如果没有此类过滤器,则返回空数组。


<?php
   print_r(filter_list());
?>

它将产生以下输出 -

Array
(
   [0] => int
   [1] => boolean
   [2] => float
   [3] => validate_regexp
   [4] => validate_domain
   [5] => validate_url
   [6] => validate_email
   [7] => validate_ip
   [8] => validate_mac
   [9] => string
   [10] => stripped
   [11] => encoded
   [12] => special_chars
   [13] => full_special_chars
   [14] => unsafe_raw
   [15] => email
   [16] => url
   [17] => number_int
   [18] => number_float
   [19] => add_slashes
   [20] => callback
)

filter_input_array() 函数

filter_input_array() 获取外部变量并选择性地过滤它们。


filter_input_array(int $type, array|int $options = FILTER_DEFAULT, 
   bool $add_empty = true): array|false|null

此函数可用于检索许多值,而无需重复调用 filter_input()

type 参数是 INPUT_GETINPUT_POSTINPUT_COOKIEINPUT_SERVER INPUT_ENV 之一。

options 参数是定义参数的数组。有效键是包含变量名称的字符串,有效值是筛选条件类型,或者是指定筛选条件、标志和选项的数组(可选)。此参数也可以是保存过滤器常数的整数。然后,输入数组中的所有值都由此筛选器筛选。

该函数在成功时返回一个数组,其中包含所请求变量的值。如果未填充由 type 指定的 input 数组,则如果未给出 FILTER_NULL_ON_FAILURE 标志,则函数返回 null,否则返回 false。对于其他失败,则返回 false

例子

要在 HTTP 请求中包含数组,我们在 “hello.html” 中使用以下 HTML 表单,并通过 POST 方法发送它。


<!DOCTYPE html>
<html>
<body>
   <h1>Filter Input Array</h1>
   <form action="hello.php" method="POST">
      <p><label for="email">Enter your email:</label>
      <input type="text" id="email" name="email"></p>
      <p><label for="age">Enter your age<label>
      <input type = "text" id="age" name="age"></p>
      <input type="submit">
   </form>
</body>
</html>

用于验证输入数组的 PHP 脚本如下所示 -


<?php
   $filters = array (
      "age" => array ("filter"=>FILTER_VALIDATE_INT,     
         "options"=>array("min_range"=>20,"max_range"=>40) ),
      "email" => FILTER_VALIDATE_EMAIL
   );
   print_r(filter_input_array(INPUT_POST, $filters));
?>

打开 HTML 表单并输入 30 作为 age,abc@example.com 作为 email,结果将是一个数组,验证两个输入 -

Array ( [age] => 30 [email] => abc@example.com )

尝试提供无效的输入,例如 “age=15”。输出数组将显示 age key 的 null 值

Array ( [age] => [email] => abc@example.com )