Skip to content

php_ref_filter

Filter 扩展是现代 PHP 开发中的重要工具,旨在验证和清理数据,尤其是来自外部来源的数据,如用户输入、表单、Cookies、Web 服务,甚至是数据库结果。正确的数据过滤对于安全和应用程序稳定性至关重要。

主要用例:

  • 验证 (Validation): 检查数据是否符合预期格式(例如,是否为有效的电子邮件地址、整数、URL?)。
  • 清理 (Sanitization): 通过移除或编码潜在有害字符来清理数据(例如,移除 HTML 标签以防止 XSS,移除 URL 中不允许的字符)。

永远不要信任外部数据!在使用它之前,务必验证和/或清理它。

Filter 扩展在 PHP 5.2.0 及更高版本中默认启用,并且是 PHP 核心的一部分。通常不需要单独安装。

虽然使用 filter_input() 或 filter_var() 等函数进行显式过滤是推荐的做法,但某些 php.ini 设置可能会影响默认的过滤行为(尽管通常不建议修改这些设置):

名称描述默认值可修改范围
filter.default默认对来自 $_GET、$_POST、$_COOKIE、$_REQUEST 和 $_SERVER 的所有数据应用指定的过滤器。接受过滤器名称(例如 string, email)。通常不建议使用此设置,而应采用显式过滤。“unsafe_raw” (不进行过滤)PHP_INI_PERDIR
filter.default_flags设置 filter.default 时应用的默认标志。请参阅下面的过滤器标志常量。null (出于历史原因曾是 FILTER_FLAG_NO_ENCODE_QUOTES)PHP_INI_PERDIR

现代最佳实践:避免依赖 filter.default。在处理输入的地方,始终使用 filter_input()、filter_var() 或相关函数进行显式过滤。

函数描述
filter_has_var()检查是否存在指定类型的变量(INPUT_GET、INPUT_POST 等)。
filter_id()返回命名过滤器对应的过滤器 ID。
filter_input()按名称获取特定的外部变量(例如,来自表单输入、服务器变量)并可选地过滤它。获取单个输入值的首选方法。
filter_input_array()获取多个外部变量并可选地过滤它们。对于同时处理多个表单字段很有用。
filter_list()返回所有支持的过滤器名称列表。
filter_var()使用指定的过滤器过滤脚本中已存在的变量。
filter_var_array()获取脚本中的多个变量并对其进行过滤。

这些常量用于过滤器函数中,以指定验证或清理的类型。

验证过滤器(检查数据是否符合标准):

Section titled “验证过滤器(检查数据是否符合标准):”
常量ID描述
FILTER_VALIDATE_BOOLEAN258验证值是否为布尔值。对于 “1”, “true”, “on”, “yes” 返回 true。对于 “0”, “false”, “off”, “no”, "" 返回 false。如果使用 FILTER_NULL_ON_FAILURE 标志,对于非布尔值返回 null,否则返回 false。
FILTER_VALIDATE_DOMAIN277验证值是否为有效的域名(根据 RFCs)。
FILTER_VALIDATE_EMAIL274验证值是否为有效的电子邮件地址。
FILTER_VALIDATE_FLOAT259验证值是否为浮点数。允许可选的小数部分和指数。
FILTER_VALIDATE_INT257验证值是否为整数。允许可选的符号、八进制、十六进制前缀。
FILTER_VALIDATE_IP275验证值是否为 IP 地址(IPv4 或 IPv6)。对于特定版本,使用 FILTER_FLAG_IPV4 或 FILTER_FLAG_IPV6 等标志。
FILTER_VALIDATE_MAC276验证值是否为 MAC 地址。
FILTER_VALIDATE_REGEXP272使用 Perl 兼容的正则表达式验证值(使用 options 参数)。
FILTER_VALIDATE_URL273验证值是否为 URL(根据 RFC 2396)。检查是否存在 scheme(例如 http, ftp)。

清理过滤器(修改数据以使其安全):

Section titled “清理过滤器(修改数据以使其安全):”
常量ID描述
FILTER_SANITIZE_EMAIL517移除除字母、数字和 !#$%&'*+-/=?^_{|}~@.[]` 之外的所有字符。
FILTER_SANITIZE_ENCODED514对字符串进行 URL 编码,可选地移除或编码特殊字符。
FILTER_SANITIZE_NUMBER_FLOAT520移除除数字、+、- 之外的所有字符,以及可选的 .、,、e、E(标志可以控制允许的分隔符/指数)。
FILTER_SANITIZE_NUMBER_INT519移除除数字、+、- 之外的所有字符。
FILTER_SANITIZE_SPECIAL_CHARS515对特殊字符('"<>& 和 ASCII 值小于 32 的字符)进行 HTML 转义。等同于调用 htmlspecialchars() 函数。
FILTER_SANITIZE_URL518移除除字母、数字和 $-_.+!*'(),{}|\^~[]”;/?:@=&` 之外的所有字符。
FILTER_UNSAFE_RAW516不进行清理。可以与 FILTER_FLAG_STRIP_LOW、FILTER_FLAG_STRIP_HIGH、FILTER_FLAG_ENCODE_LOW、FILTER_FLAG_ENCODE_HIGH、FILTER_FLAG_ENCODE_AMP 等标志结合使用。
常量状态替代方案
FILTER_SANITIZE_MAGIC_QUOTES已弃用/已移除(因为 Magic Quotes 已被移除)不需要直接替代(因为不应依赖 magic quotes)。使用适当的数据库转义(预处理语句)。
FILTER_SANITIZE_STRING / FILTER_SANITIZE_STRIPPED在 PHP 8.0 中已弃用,在 PHP 8.1 中已移除对于 HTML 输出,使用 htmlspecialchars() 函数,或根据需要进行其他特定清理/验证。不要将此过滤器用于安全目的。
常量ID描述
FILTER_CALLBACK1024调用自定义用户定义函数来过滤数据。

标志修改过滤器的行为(例如,FILTER_FLAG_ALLOW_FRACTION、FILTER_FLAG_STRIP_LOW、FILTER_NULL_ON_FAILURE)。请查阅 PHP 手册以获取完整列表:https://www.php.net/manual/en/filter.filters.flags.php

<?php
declare(strict_types=1);
// Example: Sanitize user input for HTML display
// 示例:清理用户输入以供 HTML 显示
$unsafe_comment = "<script>alert('xss');</script> This is a comment.";
$safe_comment = filter_var($unsafe_comment, FILTER_SANITIZE_SPECIAL_CHARS);
echo $safe_comment; // Output: &lt;script&gt;alert(&#039;xss&#039;);&lt;/script&gt; This is a comment.
// 输出: &lt;script&gt;alert(&#039;xss&#039;);&lt;/script&gt; This is a comment.
echo "<br>";
// Example: Validate an email address from POST data
// 示例:验证来自 POST 数据的电子邮件地址
$email = filter_input(INPUT_POST, 'user_email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
echo "Invalid email address provided."; // 提供无效的电子邮件地址
} elseif ($email === null) {
echo "Email address not provided."; // 未提供电子邮件地址
} else {
echo "Valid email: " . htmlspecialchars($email, ENT_QUOTES, 'UTF-8'); // 有效电子邮件:
}
?>

有关详细信息和更多示例,请参阅官方 PHP 文档:https://www.php.net/manual/en/book.filter.php