【问题标题】:Safe alternative to mysql_real_escape_string? (PHP)mysql_real_escape_string 的安全替代品? (PHP)
【发布时间】:2011-04-15 20:23:52
【问题描述】:

我将一个变量传递给一个执行查询的函数

MySQL 连接只发生在函数内部,并在函数内部关闭

我希望能够在将字符串发送到函数之前安全地转义字符串

我不能使用 mysql_real_escape_string,因为它需要 MySQL 连接(仅在函数内部进行)

我知道简单的答案是在函数内转义字符串,但我不能这样做,因为我需要发送一些转义的字符串和一些非转义的字符串部分

例如,我需要像这样运行函数:

myquery("'" . escape_me("My string") . "'");

请注意,我发送了两个撇号——未转义,内部带有转义字符串。出于这个原因,我不能对 myquery 函数内部的参数执行一揽子 mysql_real_escape_string。

我找到了下面的代码,建议我可以用它来替代mysql_real_escape_string:

// escape characters
function escape_me($value) {
    $return = '';
    for($i = 0; $i < strlen($value); ++$i) {
        $char = $value[$i];
        $ord = ord($char);
        if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126)
            $return .= $char;
        else
            $return .= '\\x' . dechex($ord);
    }
    return $return;
}

我不知道这个函数是否可以免受多字节攻击,但我想我每次查询时也需要撤消该函数

例如,输入: 测试3的“OK”在数据库中变成了Testing 3x27s x22OKx22

所以我的主要问题是: 你知道我是否可以使用另一个函数来替代 mysql_real_escape_string 来安全地转义字符?

【问题讨论】:

  • 有未转义内容的示例吗?

标签: php mysql


【解决方案1】:
  • 每次调用此函数时都连接是个糟糕的主意。一个好的计划应用程序不会有这么奇怪的限制。
  • 你可以使用替换,像这样
    myquery("SELECT * FROM table WHERE id = %s","My string");

  • 您可以使用另一种替换方式,一种现代方式:预准备语句。它将在许多其他答案中进行描述。

因为还没有人发布,这里是粗略的例子

function fetchAll(){
 $args = func_get_args();
 $query = array_shift($args);
 $stmt = $pdo->prepare($query);
 $stmt->execute($args);
 return $stmt->fetchAll();
}
$a=$db->fetchAll("SELECT * FROM users WHERE status=? LIMIT ?,?",$status,$start,$num);
  • 只要你使用单字节编码或者utf-8,不需要使用mysql_real_escape_string,所以mysql_escape_string(deprecated)或者addslashes就足够了

【讨论】:

  • mysql_escape_string 一直是deprecated(支持mysql_real_escape_string),但除此之外,还不错。 +1
  • 这是有道理的,为每个页面加载连接一次比为每个查询连接更好 - 我可以在函数运行之前进行 db connect,我在内部进行连接,认为打开和关闭每个查询的连接
【解决方案2】:

我建议传入要转义的值数组并使用sprintf() 格式化查询,同时转义每个值。这是我的查询功能的第一部分:

public function querya($query, $args=null){
    //check if args was passed in
    if($args !== null){
        //if an array...
        if(is_array($args)){
            //...escape each value in the args array
            foreach($args as $key=>$value){
                $args[$key] = mysql_real_escape_string($value);
            }
            //add the query to the beginning of the args array
            array_unshift($args, $query);
            //call sprintf with the array as arguments to sprintf
            $query = call_user_func_array("sprintf", $args);
        } else {
            //if args is not an array, then string (single argument passed in).
            $query = sprintf($query, mysql_real_escape_string($args));
        }
    }

    //perform query, other stuff
}

【讨论】:

  • 在类似的函数中,我将引号添加到 %s 通配符中,以确保查询中没有 %s 未加引号。
  • 有道理。这只是我自己使用的,所以我通常会编写像$DB-&gt;querya("SELECT COLUMN FROM TABLE WHERE VALUE='%s' AND 1=%d",array('test',1)); 这样的查询,并在需要时在查询中包含 %s 周围的引号。
猜你喜欢
  • 1970-01-01
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
  • 2019-07-20
  • 2011-01-01
  • 2020-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多