You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义query_var函数能否实现数据库查询变量的通用sanitize?

关于使用mysqli_real_escape_string()处理数据库查询变量的疑问

多数开发者推荐使用预处理语句,但现有站点存在大量已有的查询,因此希望通过mysqli_real_escape_string()函数来净化数据库查询变量。mysqli_query()的PHP手册也说明该函数是可接受的替代方案,故提出以下问题:

计划使用如下查询方式:

$query = sprintf("SELECT * FROM users WHERE user_name = %s", 
                    query_var($user_name, "text"));
$Records = mysqli_query($db, $query) or die(mysqli_error($db));

想确认下方自定义的query_var函数是否可行,存在以下疑问:

  • 是否仍需在开头执行stripslashes()?之前使用Adobe Dreamweaver的旧函数包含此操作。
  • 在mysqli_real_escape_string()后添加引号(如$the_value = "'".$the_value."'")是否可行?
  • 该函数是否存在明显的重大缺陷?

另外注意到stripslashes()会将多个\\转换为单个,这可能不适用于通用场景,例如用户提交包含\\的文本评论或商品描述时,不使用stripslashes()是否可行?

主要关注SQL注入问题,提交数据含HTML标签无影响,将在输出/打印时处理。

附自定义函数代码:

if(!function_exists('query_var')){
    function query_var($the_value, $the_type="text"){ 
        global $db;
        // do I still need this ?
        // $the_value = stripslashes($the_value);
        $the_value = mysqli_real_escape_string($db, $the_value);
        // do not allow dummy type of variables
        if(!in_array($the_type, array('text', 'int', 'float', 'double'))){
            $the_type='text';
        }
        if($the_type=='text'){
            $the_value = "'".$the_value."'";
        } 
        if($the_type=='int'){
            $the_value = intval($the_value);
        }
         if($the_type == 'float' or $the_type=='double'){
            $the_value = floatval($the_value);
        } 
        return $the_value;
    }
}

解答
  • 是否需要执行stripslashes()?
    不需要。stripslashes()是为了兼容旧版PHP中magic_quotes_gpc开启时自动添加的转义符,而PHP5.4及以后该配置已被移除,默认处于关闭状态。如果强行使用,会错误移除用户输入的合法反斜杠(比如用户输入的路径C:\\Users\\xxx会变成C:\Users\xxx),破坏原始内容。直接注释掉这行即可,不会影响SQL注入防护效果。

  • 在mysqli_real_escape_string()后添加引号是否可行?
    可行且必要。mysqli_real_escape_string()仅负责转义字符串中的特殊字符(如单引号、反斜杠),不会自动为文本值添加SQL语句所需的单引号包裹。转义后再手动添加单引号,能确保文本值在SQL语句中是合法的字符串格式,既避免语法错误,也能有效防范SQL注入。

  • 该函数是否存在明显重大缺陷?
    有几个需要优化的点,但不算致命缺陷:

    1. 依赖全局数据库连接:函数依赖全局变量$db,若后续代码结构调整(比如改用类封装数据库操作),函数会直接失效。建议将$db作为参数传入函数,提升独立性和可维护性。
    2. 浮点类型处理的精度风险:floatval()处理部分字符串时可能出现精度丢失,且直接拼接进SQL语句时,不同数据库的浮点格式兼容性较差。如果是金额这类对精度要求高的场景,建议将其当作文本处理(转义加引号),或改用预处理语句。
    3. 类型判断代码冗余:多个独立的if判断可合并为switch语句,代码会更简洁,但不影响功能逻辑。
  • 不使用stripslashes()是否可行?
    完全可行,甚至是推荐做法。如前所述,当前PHP环境已无magic_quotes_gpc的问题,保留用户输入的原始反斜杠是正确的选择。mysqli_real_escape_string()会正确处理这些反斜杠,既不会引发SQL注入,也能完整保留用户提交的原始内容。


内容的提问来源于stack exchange,提问作者adrianTNT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:45:35