2
  1. PDO 中是​​否有任何替代方案,如 mysql 中的 mysql_real_escape_string?
  2. 为什么我们应该设置 'false' -> ATTR_EMULATE_PREPARES 常量?
4

2 回答 2

9

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

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

为避免语法错误在最坏的情况下可被用作 SQL 注入,您需要在此处申请mysql_real_escape_string以正确转义该值。如果您不知道这意味着什么,请阅读The Great Escapism(或:使用文本中的文本需要知道的内容) 。$bar

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

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

这实际上是作为两个单独的部分发送到数据库的;语法永远不会被弄乱或利用,因为这两个部分从未真正开始合并。

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

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

在任何情况下,您都不要将 mysql 扩展中的函数与 PDO 扩展一起使用;它一开始是行不通的,因为mysql_real_escape_string需要通过mysql_connect.

于 2013-06-12T07:26:03.570 回答
0
  1. 您不必在准备好的语句中的 PDO 中使用 mysql_real_escape_string
  2. 不必要。您可以使用任何一种方式

回答编辑的问题

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

于 2013-06-12T07:09:31.867 回答