为什么使用FILTER_SANITIZE_STRING会移除SQL字符串的部分内容?
问题根因
你遇到的SQL内容丢失问题完全是DBParameters::SetSQL方法内的过滤器使用错误导致的:
FILTER_SANITIZE_STRING过滤器是为HTML场景设计的,默认会把所有<开头、>结尾的连续字符判定为HTML标签直接整体删除,你传入的参数FILTER_FLAG_NO_ENCODE_QUOTES只控制是否转义引号,不会修改过滤器剥离标签的核心逻辑。- 你的SQL语句中恰好存在
<(<=运算符的左半部分)和后续的>(>=运算符的左半部分),两个符号之间的所有内容:包括= ?后的换行、注释-- 3、换行、and period_id全部被过滤器当做标签内容删除,最终原本的period_id <= ?\n-- 3\nand period_id >= ?片段过滤后只剩下period_id = ?,和你日志输出的异常SQL完全吻合。
验证逻辑
你可以运行以下代码复现问题:
$testFragment = "where period_id <= ? -- 3 and period_id >= ?"; echo filter_var($testFragment, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
执行后输出就是where period_id = ?,和你遇到的异常结果一致。
修复方案
- 直接删除
SetSQL方法中的filter_var处理逻辑。SQL语句不需要使用面向HTML的过滤器做清理,SQL注入的防护完全可以通过你已经在用的参数绑定实现,额外的HTML过滤反而会带来这类不可预期的错误。 - 如果你确实需要对输入的SQL做基础清理,仅保留去除不可见控制字符、首尾去空格这类通用文本处理即可,不要使用HTML场景的过滤函数。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

