2014-11-22 45 views
-2

我试图转义一个字符串,我将其放入一个语句。PDO mysql_real_escape_string如何在准备好的陈述中使用

我知道PDO准备并执行(对于那些不知道PDO的人准备一个语句来停止任何额外的命令被运行,所以语句知道在注入变量数据之前它正在运行什么,从而消除了被注入)我现在的麻烦是我想用MySQL规则之外的变量来运行一个语句(见下文)。

$sql = $this->PDO->prepare("SELECT * FROM `weight` WHERE `user_id`=:id ORDER BY $order $direction"); 

正如你可以看到我使用自定义的顺序由和ASC/DESC上述作品statment,但我不觉得这是足够安全的。把方向作为一个switch语句很容易,但为了将来的扩展,我想逃避$ order而不是使用开关或硬编码数组。

我在$ order中使用了许多方法的mysql_real_escape_string,但声明不喜欢它,有什么想法吗?编辑----功能下面,没有猜测工作真正需要的全部代码..

public function getWeightByUserOrderBy($id, $order, $direction) { 
$order1 = $PDO->quote($order); 
    $sql = $this->PDO->prepare("SELECT * FROM `weight` WHERE `user_id`=:id ORDER BY $order1 $direction"); 
    $sql->execute(array(
     ":id" => $id 
    )); 
    $sql = $sql->fetchall(); 
    return $sql; 
} 
+1

*“我在$ order中使用了许多方法的mysql_real_escape_string,但是语句不喜欢它”* - **答案:**这是因为当您混用API时,MyQL不喜欢它。仅使用一种API类型。显示完整的代码并阅读[** PDO与准备语句**](http://php.net/pdo.prepared-statements)是如何工作的。 – 2014-11-22 23:05:24

+2

如果您完全控制了查询内容,则没有注入的范围。 '$ order'和'$ direction'的内容应该针对白名单进行验证,并且只使用_your_值。您根本不需要使用'real_escape_string()',特别是使用不同的&弃用的API。 – 2014-11-22 23:13:10

+1

要添加到@ MikeW的评论,您不能使用'mysql_real_escape_string'而不使用'$ order'并且不使用PDO特定的转义函数。转义函数仅适用于值而不适用于列名。因此,如果'$ order'的值是用户提供的,那么您总是需要一个硬编码数组(白名单)来检查。该数组可以填充查询数据库的列名当然... – jeroen 2014-11-22 23:30:38

回答

0

你不会想用mysql_real_escape_string,从一个过时的接口。

对于$direction,请验证它是否包含DESCDESCENDING。否则,将其设置为空字符串或ASC

如果$order应该包含标识符(列名),那么您可以使用反引号将其转义,并删除变量中的任何反引号。如果$order包含表达式,那有点棘手。

+1

*“您不希望使用来自已弃用接口的'mysql_real_escape_string'”。 * - OP使用PDO(最少发布1行代码);它真的归结为这两个API不混合,正如我在OP的问题下的评论中所说的那样。 OP应该发布完整的代码以避免所有的猜测。 – 2014-11-22 23:17:02