PHP 入门教程
32.2
32.3
32.4 用
32.5 过滤数组:
PHP 过滤器
本教程共 65 篇 · 第 32 篇 · 更新于 2026-07-24 · 约 5 分钟阅读
PHPPHP8过滤器filter_var数据净化XSS
32. PHP 过滤器
本节目标:熟练使用
filter_var和filter_input,区分验证(Validate)与净化(Sanitize),处理常见数据类型。
用户输入的数据往往”鱼龙混杂”。PHP 过滤器扩展提供了一套标准工具,帮你验证格式是否正确,或清理掉不安全的字符。
32.1 验证 vs 净化
| 类型 | 作用 | 示例 |
|---|---|---|
| 验证(Validate) | 检查数据是否符合格式,返回原值或 false | 邮箱格式对不对 |
| 净化(Sanitize) | 移除非法字符,返回清理后的值 | 去掉标签、转义特殊符号 |
<?php
$email = "test@example.com<script>";
// 验证:格式不对就返回 false
$valid = filter_var($email, FILTER_VALIDATE_EMAIL);
var_dump($valid); // false
// 净化:移除非法字符
$clean = filter_var($email, FILTER_SANITIZE_EMAIL);
echo $clean; // test@example.comscript
Note净化不保证格式正确,只是清理字符。重要数据应该先净化再验证。
32.2 filter_var() 验证常用类型
<?php
// 整数
$age = "25";
var_dump(filter_var($age, FILTER_VALIDATE_INT)); // int(25)
var_dump(filter_var("abc", FILTER_VALIDATE_INT)); // false
// 布尔值
$flag = "yes";
var_dump(filter_var($flag, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); // bool(true)
// 浮点数
$price = "19.99";
var_dump(filter_var($price, FILTER_VALIDATE_FLOAT)); // float(19.99)
// IP 地址
$ip = "192.168.1.1";
var_dump(filter_var($ip, FILTER_VALIDATE_IP)); // string(...)
var_dump(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)); // 仅 IPv4
// MAC 地址
$mac = "00:1A:2B:3C:4D:5E";
var_dump(filter_var($mac, FILTER_VALIDATE_MAC)); // string(...)
32.3 filter_var() 净化常用类型
<?php
$input = "<p>Hello <script>alert('xss')</script> World!</p>";
// 编码特殊字符(防 XSS,等价于 htmlspecialchars)
$encoded = filter_var($input, FILTER_SANITIZE_SPECIAL_CHARS);
echo $encoded;
// 输出:<p>Hello <script>alert('xss')</script> World!</p>
// 只保留允许的标签(真正移除标签)
$allowedTags = "<p><br><strong>";
$safe = strip_tags($input, $allowedTags);
echo $safe;
// 另一个选择:完整编码所有特殊字符
$fullEncoded = filter_var($input, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
echo $fullEncoded;
Tip
FILTER_SANITIZE_FULL_SPECIAL_CHARS是htmlspecialchars()的过滤器版本,PHP 8.1 起推荐使用。
32.4 用 filter_input() 直接处理超全局变量
filter_input() 比直接访问 $_GET/$_POST 更安全,因为它不会触发未定义索引的警告:
<?php
// 获取 GET 参数并验证为整数
$page = filter_input(INPUT_GET, "page", FILTER_VALIDATE_INT) ?: 1;
// 获取 POST 邮箱并验证
$email = filter_input(INPUT_POST, "email", FILTER_VALIDATE_EMAIL);
if ($email === false) {
echo "邮箱格式错误";
}
// 获取 COOKIE 并净化
$username = filter_input(INPUT_COOKIE, "user", FILTER_SANITIZE_SPECIAL_CHARS);
输入类型常量
| 常量 | 对应超全局变量 |
|---|---|
INPUT_GET | $_GET |
INPUT_POST | $_POST |
INPUT_COOKIE | $_COOKIE |
INPUT_SERVER | $_SERVER |
INPUT_ENV | $_ENV |
32.5 过滤数组:filter_var_array()
批量过滤表单数据非常方便:
<?php
$filters = [
"name" => [
"filter" => FILTER_SANITIZE_SPECIAL_CHARS,
"flags" => FILTER_FLAG_STRIP_LOW,
],
"age" => [
"filter" => FILTER_VALIDATE_INT,
"options" => ["min_range" => 1, "max_range" => 150],
],
"email" => FILTER_VALIDATE_EMAIL,
"website" => FILTER_VALIDATE_URL,
"score" => FILTER_VALIDATE_FLOAT,
];
$result = filter_var_array($_POST, $filters);
if ($result["age"] === false) {
echo "年龄必须在 1-150 之间";
}
if ($result["email"] === false) {
echo "邮箱格式不正确";
}
Note验证失败时,对应字段返回
false。若字段不存在,返回null。注意区分false和null。
32.6 自定义过滤回调
<?php
$input = " Hello World 123! ";
// 使用回调自定义过滤逻辑
$result = filter_var($input, FILTER_CALLBACK, [
"options" => function (string $value): string {
return preg_replace('/[^a-zA-Z\s]/', '', trim($value));
}
]);
echo $result; // Hello World
32.7 常见错误提醒
- 混淆验证与净化结果:验证失败返回
false,净化总是返回字符串 - 整数验证的
0陷阱:filter_var("0", FILTER_VALIDATE_INT)返回0,判断时要用=== false - URL 验证需带协议:
example.com不会通过FILTER_VALIDATE_URL,必须是http://example.com
来源:参考了 runoob「PHP 过滤器」「PHP 高级过滤器」、w3cschool「PHP 过滤器」「PHP 高级过滤器」等,改写后所得。