PHP 处理 GET/POST 数据的安全过滤与编码实践
在 Web 应用开发中,对来自客户端的 GET 和 POST 数据进行严格清洗是防止 SQL 注入和 XSS 攻击的关键步骤。本文将详细解析几种经典的 PHP 数据处理函数,包括递归去转义、HTML 实体编码以及基于文件列表的自定义关键字过滤,并提供实际代码示例。
结果与目标
确保所有用户提交的数据在经过处理后不包含恶意脚本代码、不被污染的 HTML 标签以及预定义的敏感词汇,同时保持数据的可用性和完整性。
准备条件
- 运行环境为安装了 PHP 的服务器。
- 对于高级文本过滤功能,需要准备包含“普通非法关键字”和“重要非法关键字”的文本文件(如
common_list.txt和signify_list.txt)。
第1步:处理递归去转义逻辑
目的: 适配旧版 PHP 环境或特定配置下的字符串转义状态,确保数组嵌套结构的正确性。
入口: 初始化脚本或全局配置文件。
动作: 检查是否开启自动转义,若未开启则对 _GET 和 _POST 超全局变量应用 stripslashes_array 函数进行递归清理。
// php 批量过滤post,get敏感数据
if (get_magic_quotes_gpc()) {
$_GET = stripslashes_array($_GET);
$_POST = stripslashes_array($_POST);
}
function stripslashes_array(&$array) {
while(list($key,$var) = each($array)) {
if ($key != 'argc' && $key != 'argv' && (strtoupper($key) != $key || ''.intval($key) == "$key")) {
if (is_string($var)) {
$array[$key] = stripslashes($var);
}
if (is_array($var)) {
$array[$key] = stripslashes_array($var);
}
}
}
return $array;
}
第2步:实施基础 HTML 实体编码
目的: 将特殊字符转换为 HTML 实体,从根本上阻断 XSS 脚本执行。
入口: 数据录入接口或模板渲染前。
动作: 使用 htmlspecialchars 直接编码特定字段;或者参考以下逻辑进行更细致的替换操作(注:现代开发建议优先直接使用核心库函数)。
$xxx = htmlspecialchars($_POST['xxx']);
// 或者获取 GET 参数
$xxx = htmlspecialchars($_GET['xxx']);
此外,还可以配合自定义的 htmlencode 函数进行字符替换,例如将引号、小于大于号及空格等进行标准化处理。
第3步:构建基于关键词列表的高级过滤器
目的: 拦截特定的语义风险内容(如敏感政治词汇、黑产关键词等),支持精确匹配和模糊匹配两种模式。
入口: 表单提交验证中间件。
重要参数: $match_type(1为精确匹配,2为模糊匹配)。
动作:
- 读取词库: 检查
common_list.txt和signify_list.txt是否存在,并加载至内存数组。 - 预处理: 调用
lib_replace_end_tag去除潜在的 HTML 尾标签干扰。 - 执行匹配:
- 精确匹配: 遍历普通过滤列表,利用正则
/^$string$/i判断是否完全一致。 - 模糊匹配: 先检查通用词,再遍历严重非法词库,利用
preg_match("/$block/i", $string)查找子串是否存在。
- 精确匹配: 遍历普通过滤列表,利用正则
function lib_lawless_string_filter($string, $match_type=1)
{
$string = trim($string);
if (empty($string)) return false;
$common_file = "common_list.txt";
$signify_file = "signify_list.txt";
if (!file_exists($common_file) || !file_exists($signify_file)) {
return false;
}
$common_list = file($common_file);
$signify_list = file($signify_file);
$is_lawless = false;
if ($match_type == 1) {
$is_lawless = exact_match($string, $common_list);
}
if ($match_type == 2) {
$is_lawless = blur_match($string, $common_list, $signify_list);
}
if (is_array($is_lawless) && !empty($is_lawless)) {
return true;
} else {
return false;
}
}
第4步:解码还原(如需展示原文)
目的: 将经过编码存储的数据还原为可读文本。
动作: 逆序执行编码过程,注意顺序应优先处理简单的符号转换,最后处理可能受影响的语义块。
function htmldecode($str){
if(empty($str)) return;
if($str=="") return $str;
// 依次执行 str_replace 反转操作
// ... 此处省略具体的长串 str_replace,原理同编码相反
return $str;
}
完成判断
当用户输入的数据通过上述任意一层过滤器且返回结果为“合法/空数组”,或经过编码后数据库存储的内容不再包含可执行的 Script 标签时,视为处理成功。
简要总结
PHP 数据过滤的核心在于“输入时编码,输出时视情况解码”,以及结合业务场景定制黑名单规则。虽然文中提及的部分旧版兼容写法(如 Magic Quotes)在现代 PHP 版本中已不再适用,但其体现的递归处理和分词匹配思想仍具参考价值。建议在新的项目中优先考虑 PDO 预处理语句防注入,并使用 XSS Protection 扩展库辅助过滤。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









