Skip to content

PHP 高级过滤器

除了基本的验证(validation)和清理(sanitization)之外,PHP 过滤器扩展还提供了标志(flags)和选项(options)用于更具体的过滤任务,以及一次过滤多个输入的机制。

许多过滤器在 filter_var()(及相关函数)中接受一个 options 参数。这可以是一个包含标志的整数,也可以是一个指定选项和标志的关联数组(associative array)。

FILTER_VALIDATE_INT 过滤器接受 min_range 和 max_range 选项。

<?php
$input = 122;
$min = 1;
$max = 100; // Note: 122 is outside this range
$options = [
'options' => [
'min_range' => $min,
'max_range' => $max
],
'flags' => FILTER_NULL_ON_FAILURE // Use null on failure for clarity
];
$validatedInt = filter_var($input, FILTER_VALIDATE_INT, $options);
if ($validatedInt !== null) {
echo "值 {$input} 在合法范围 [{$min}, {$max}] 内。<br>";
} else {
echo "值 {$input} 不在合法范围 [{$min}, {$max}] 内。<br>";
}
$inputInRange = 50;
$validatedIntInRange = filter_var($inputInRange, FILTER_VALIDATE_INT, $options);
if ($validatedIntInRange !== null) {
echo "值 {$inputInRange} 在合法范围 [{$min}, {$max}] 内。<br>";
} else {
echo "值 {$inputInRange} 不在合法范围 [{$min}, {$max}] 内。<br>";
}
?>

使用 FILTER_FLAG_IPV6 标志与 FILTER_VALIDATE_IP 一起使用,以要求 IPv6 格式。

<?php
$ipv6 = "2001:0db8:85a3:08d3:1319:8a2e:0370:7334";
$ipv4 = "192.168.1.1";
if (filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
echo "'{$ipv6}' 是一个有效的 IPv6 地址。<br>";
} else {
echo "'{$ipv6}' 不是一个有效的 IPv6 地址。<br>";
}
// This will fail because FILTER_FLAG_IPV6 requires an IPv6 address
if (filter_var($ipv4, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
echo "'{$ipv4}' 是一个有效的 IPv6 地址。<br>";
} else {
echo "'{$ipv4}' 不是一个有效的 IPv6 地址(使用了 IPv6 标志)。<br>";
}
?>

使用 FILTER_FLAG_QUERY_REQUIRED 标志与 FILTER_VALIDATE_URL 一起使用。

<?php
$urlWithQuery = "https://example.com/search?q=php";
$urlWithoutQuery = "https://example.com/";
// Check if URL is valid AND has a query string
if (filter_var($urlWithQuery, FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED)) {
echo "'{$urlWithQuery}' 是一个包含查询字符串的有效 URL。<br>";
} else {
echo "'{$urlWithQuery}' 不是一个包含查询字符串的有效 URL。<br>";
}
// This will fail because it lacks a query string
if (filter_var($urlWithoutQuery, FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED)) {
echo "'{$urlWithoutQuery}' 是一个包含查询字符串的有效 URL。<br>";
} else {
echo "'{$urlWithoutQuery}' 不是一个包含查询字符串的有效 URL。<br>";
}
?>

验证包含 Unicode 字符的电子邮件地址

Section titled “验证包含 Unicode 字符的电子邮件地址”

使用 FILTER_FLAG_EMAIL_UNICODE 标志(自 PHP 7.1 起可用)来允许电子邮件地址本地部分(local part)包含 Unicode 字符。

<?php
$unicodeEmail = 'josé.philipe@example.com';
// Standard validation might fail depending on PHP version and config
if (filter_var($unicodeEmail, FILTER_VALIDATE_EMAIL)) {
echo "'{$unicodeEmail}' 通过了标准验证。<br>";
} else {
echo "'{$unicodeEmail}' 未通过标准验证。<br>";
}
// Using the flag to explicitly allow Unicode
if (filter_var($unicodeEmail, FILTER_VALIDATE_EMAIL, FILTER_FLAG_EMAIL_UNICODE)) {
echo "'{$unicodeEmail}' 使用 Unicode 标志通过验证。<br>";
} else {
echo "'{$unicodeEmail}' 使用 Unicode 标志未通过验证。<br>";
}
?>

关于废弃标志的说明:一些标志,如 FILTER_FLAG_STRIP_LOW、FILTER_FLAG_STRIP_HIGH 和 FILTER_FLAG_ENCODE_HIGH(通常与已废弃的 FILTER_SANITIZE_STRING 一起使用),在最新的 PHP 版本中也已被废弃或移除。对于移除控制字符或处理字符编码等任务,请使用相应的字符串函数(例如 preg_replace、mb_convert_encoding)或专门的库。

PHP 提供了函数可以更高效地将过滤器应用于整个输入数组,例如 $_GET、$_POST、$_COOKIE、$_SERVER 和 $_ENV。

filter_input():通过名称获取特定的外部变量,并可选地对其进行过滤。

filter_input_array():根据一个定义数组,过滤来自 GET、POST 等源的多个输入变量。

filter_var_array():根据一个定义数组,过滤现有数组中的多个值。

使用 filter_input_array() 过滤 $_POST 数据的示例:

Section titled “使用 filter_input_array() 过滤 $_POST 数据的示例:”

假设一个 HTML 表单通过 POST 提交 ‘email’、‘age’ 和 ‘website’。

<?php
// Define the filters to apply to the POST data
$filter_definition = [
'email' => FILTER_VALIDATE_EMAIL,
'age' => [
'filter' => FILTER_VALIDATE_INT,
'options' => ['min_range' => 1, 'max_range' => 120]
],
'website' => FILTER_VALIDATE_URL,
'comment' => [
'filter' => FILTER_SANITIZE_SPECIAL_CHARS // Sanitize comments
]
];
// Apply the filters to the POST superglobal
$filtered_post = filter_input_array(INPUT_POST, $filter_definition);
// Check the results
if ($filtered_post !== null) {
var_dump($filtered_post);
// Example check for a specific field's validity
if ($filtered_post['age'] === false) {
echo "<p>提供的年龄无效(必须在 1 到 120 之间)。</p>";
}
if ($filtered_post['email'] === false) {
echo "<p>电子邮件地址格式无效。</p>";
}
} else {
echo "<p>未接收到 POST 数据或过滤过程中发生错误。</p>";
}
?>

这种方法提供了一种结构化的方式,可以同时验证和清理多个输入。

有关所有可用过滤器、标志、选项和函数的详细信息,请参阅官方 PHP 文档: