PHP FILTER_SANITIZE_STRIPPED 过滤器(千字长文)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

前言

在 PHP 开发中,输入过滤是一个核心的安全实践。用户提交的数据可能包含恶意代码或意外内容,例如 HTML 标签、特殊字符等,这些内容若未经处理直接用于应用程序,可能导致严重的安全漏洞(如 XSS 攻击)。PHP FILTER_SANITIZE_STRIPPED 过滤器正是为此而生,它能够高效地剥离输入中的 HTML 标签,仅保留纯文本内容。本文将从基础概念到实战应用,逐步讲解这一工具的使用方法和注意事项,帮助开发者构建更安全的应用程序。


什么是 PHP 过滤器?

PHP 的过滤扩展(Filter Extension)提供了一套预定义的过滤器(Filter),用于验证和清理输入数据。这些过滤器分为两大类:验证过滤器清理过滤器

  • 验证过滤器:检查数据是否符合特定规则(例如是否为合法的电子邮件地址),但不会修改原始数据。
  • 清理过滤器:直接修改数据,去除不需要的部分,使其符合预期格式。

FILTER_SANITIZE_STRIPPED 属于清理过滤器,其核心功能是删除输入字符串中的所有 HTML 和 PHP 标签,同时保留纯文本内容。


FILTER_SANITIZE_STRIPPED 的基本用法

基础语法

PHP 中通过 filter_var() 函数配合过滤器常量使用:

$clean_data = filter_var($input, FILTER_SANITIZE_STRIPPED);  

示例:剥离 HTML 标签

假设用户提交了以下包含 HTML 标签的输入:

$user_input = "<p>欢迎访问本站</p><script>alert('恶意代码')</script>";  

使用过滤器处理后:

$clean_data = filter_var($user_input, FILTER_SANITIZE_STRIPPED);  
echo $clean_data; // 输出:"欢迎访问本站恶意代码"  

关键特性

  1. 完全删除标签:不仅去除标签本身,还会删除标签内的内容。例如 <img src="..." /> 会被直接删除,而非保留 src 值。
  2. 保留文本内容:所有非标签的字符(如文字、数字、特殊符号)均会被保留。
  3. 兼容性:支持 PHP 5.2.0 及以上版本,但推荐使用最新版本以获得最佳兼容性。

过滤器与类似工具的对比

与 FILTER_SANITIZE_STRING 的区别

FILTER_SANITIZE_STRIPPED 和 FILTER_SANITIZE_STRING 均用于清理字符串,但行为不同:

过滤器功能描述
FILTER_SANITIZE_STRIPPED删除所有 HTML 和 PHP 标签,保留纯文本
FILTER_SANITIZE_STRING转义 HTML 标签(如将 < 转为 &lt;),而非删除

示例对比

$input = "<b>加粗文字</b>";  

// 使用 FILTER_SANITIZE_STRIPPED  
echo filter_var($input, FILTER_SANITIZE_STRIPPED); // 输出:"加粗文字"  

// 使用 FILTER_SANITIZE_STRING  
echo filter_var($input, FILTER_SANITIZE_STRING); // 输出:&lt;b&gt;加粗文字&lt;/b&gt;  

与 strip_tags() 函数的异同

PHP 内置的 strip_tags() 函数功能与 FILTER_SANITIZE_STRIPPED 类似,但存在以下差异:

  • 参数灵活性strip_tags() 可指定允许保留的标签(例如 <p>),而 FILTER_SANITIZE_STRIPPED 不支持此功能。
  • 编码兼容性:FILTER_SANITIZE_STRIPPED 在处理特殊字符(如 UTF-8 编码)时更可靠。

实际应用场景

场景 1:表单输入的净化

当用户在评论区提交内容时,可能包含恶意脚本或格式化标签。通过过滤器确保仅保存纯文本:

// 假设用户提交的评论内容  
$comment = "<div>这是评论</div><script>alert('XSS')</script>";  

// 使用过滤器净化数据  
$clean_comment = filter_var($comment, FILTER_SANITIZE_STRIPPED);  

// 数据存储到数据库  
$db->query("INSERT INTO comments (content) VALUES (?)", [$clean_comment]);  

场景 2:API 数据的预处理

在处理外部 API 返回的数据时,若需确保字段不含 HTML 内容:

// 模拟 API 响应  
$api_response = [  
    "title" => "<h1>标题</h1>",  
    "description" => "描述内容"  
];  

// 过滤所有文本字段  
$clean_data = array_map(function($value) {  
    return filter_var($value, FILTER_SANITIZE_STRIPPED);  
}, $api_response);  

// 输出:标题(无 HTML 标签)  

注意事项与最佳实践

1. 过滤 ≠ 验证

尽管 FILTER_SANITIZE_STRIPPED 能净化数据,但它不会验证数据是否符合预期格式。例如:

$email = "<EMAIL>";  
$clean_email = filter_var($email, FILTER_SANITIZE_STRIPPED); // 输出:"example@com"  

// 需额外验证邮箱格式是否合法  
if (!filter_var($clean_email, FILTER_VALIDATE_EMAIL)) {  
    // 报错处理  
}  

2. 特殊字符的保留

过滤器会保留大部分特殊字符(如 !@#$%^),但需注意:

  • 若需进一步清理特殊字符,可结合 FILTER_SANITIZE_SPECIAL_CHARSFILTER_SANITIZE_ENCODED
  • 对于密码等敏感字段,应避免直接过滤,转而使用哈希加密。

3. 性能考量

频繁调用 filter_var() 可能影响性能,建议:

  • 在数据进入业务逻辑前统一处理(例如在模型层或服务层)。
  • 对于非敏感字段(如日志记录),可选择性跳过过滤。

常见问题与解决方案

Q:如何保留部分 HTML 标签?

A:FILTER_SANITIZE_STRIPPED 不支持保留标签,可改用 strip_tags() 或自定义白名单:

// 仅允许 <p> 标签  
$allowed_tags = ['<p>'];  
$clean_content = strip_tags($input, implode('', $allowed_tags));  

Q:过滤后的数据是否需要转义?

A:若数据用于 HTML 输出,建议再通过 htmlspecialchars() 转义:

echo htmlspecialchars($clean_data, ENT_QUOTES, 'UTF-8');  

Q:如何处理多维数组?

A:使用 array_walk_recursive() 遍历并过滤所有字符串值:

function sanitize_array(&$value) {  
    if (is_string($value)) {  
        $value = filter_var($value, FILTER_SANITIZE_STRIPPED);  
    }  
}  

array_walk_recursive($data_array, 'sanitize_array');  

结论

PHP FILTER_SANITIZE_STRIPPED 过滤器是一个简单但强大的工具,能够有效防范因 HTML 标签注入引发的安全风险。通过本文的讲解,开发者可以掌握其核心功能、使用场景以及与类似工具的差异。然而,安全开发需要多层防护:过滤、验证、转义缺一不可。建议将其与输入验证(如 FILTER_VALIDATE_EMAIL)、输出编码(如 htmlspecialchars())结合,构建更健壮的应用程序。

在实际开发中,务必根据业务需求选择合适的过滤策略,并定期审查代码以适应新的安全威胁。只有将理论与实践结合,才能真正发挥过滤器的价值,为用户提供可靠的服务。

最新发布