为什么要使用ATTR_EMULATE_PREPARES,是mysql_real_escape_string的替代品吗?在PDO中

时间:2013-06-12 06:54:45

标签: php mysql pdo prepared-statement sql-injection

  1. 在PDO中是否有任何替代方法,因为在mysql中是mysql_real_escape_string?
  2. 为什么我们应该设置'false' - > ATTR_EMULATE_PREPARES常数?

2 个答案:

答案 0 :(得分:9)

使用mysql扩展,将值动态嵌入查询的唯一方法是:

$query = "SELECT ... WHERE foo = '$bar'";

为了避免语法错误,在最坏的情况下可以将其用作SQL注入,您需要在此处mysql_real_escape_string应用$bar以正确地转义值。如果您不知道这意味着什么,请阅读The Great Escapism (Or: What You Need To Know To Work With Text Within Text)

预备语句通过完全分离查询和值来提供一种完全不同的方式来使用动态值:

$stmt = $db->prepare('SELECT ... WHERE foo = :bar');
$stmt->execute(array(':bar' => $bar));

这实际上是作为两个单独的部分发送到数据库;语法永远不会搞砸或利用,因为这两个部分实际上从未合并过。

但是,所有数据库都不支持此功能,但某些(较旧的)数据库仍需要旧样式,未准备好的转义查询。 ATTR_EMULATE_PREPARES模拟准备好的语句提供了选项。您仍然可以在代码中使用$db->prepare()->execute() API,但在幕后,PDO将转义值并将其连接到查询中。要明确禁止PDO执行此操作并强制它使用数据库提供的本机预准备语句API,请将ATTR_EMULATE_PREPARES设置为false

如果您的数据库本身支持预准备语句,则应该这样做;所有最近的数据库中途都有。如果你让PDO模拟准备好的语句,那么在某些条件下SQL注入的可能性很小(主要是在人工构造的多字节连接编码情况下AFAIK)。

在任何情况下都不使用mysql扩展中的函数和PDO扩展;由于mysql_real_escape_string需要通过mysql_connect建立单独的数据库连接,因此无法开始使用。

答案 1 :(得分:0)

  1. 您不必在准备好的声明中使用PDO中的mysql_real_escape_string
  2. 不一定。您可以使用任何一种方式
  3. 回答编辑过的问题

    ,没有其他选择。您应该使用准备好的陈述。