7

我阅读了 PDO 并在 StackOverFlow 上搜索了有关 pdo 和准备语句的信息。我想知道有什么好处或使用准备语句。例如:

$sql = 'SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();

对比

$sql = "SELECT name, colour, calories FROM fruit WHERE calories < $calories AND colour = $colour";
$result = $connection->query($query);
$row = $result->fetch(PDO::FETCH_ASSOC);

两个查询都将返回相同的结果,所以为什么要使用准备,对我来说它看起来会更慢,因为你必须执行一个额外的步骤。

谢谢

4

4 回答 4

12

准备好的陈述是:

  1. 更安全:PDO 或底层数据库库将负责为您转义绑定的变量。如果您始终使用准备好的语句,您将永远不会受到 SQL 注入攻击。
  2. (有时)更快:许多数据库会缓存预准备语句的查询计划,并通过符号引用预准备语句,而不是重新传输整个查询文本。如果您只准备一次语句,然后使用不同的变量重用准备好的语句对象,则这一点最为明显。

在这两者中,#1更为重要,它使准备好的语句变得不可或缺!如果您不使用准备好的语句,那么唯一明智的做法就是在软件中重新实现此功能。(当我被迫使用mysql驱动程序并且无法使用时,我已经做了几次PDO。)

于 2011-11-27T14:19:22.383 回答
1

使用大量查询(您已经准备好查询)时,准备速度更快,而且更安全。

您的第二个代码可能不起作用 - 您在查询中使用参数,但您没有定义它们。

使用 query(),您必须使用 quote() 手动填写查询 - 这是更多的工作,并且往往会使程序员粗心。

于 2011-11-27T14:09:33.140 回答
0

实际上,您错过了第三个选项:

$stmt = $dbh->prepare( '
   SELECT 
       name, 
       colour, 
       calories 
   FROM fruit 
   WHERE calories < :calories 
     AND colour = :colour
');
$stmt->bindParam( ':calories', $calories, PDO::PARAM_INT );
$stmt->bindParam( ':colour', $colour, PDO::PARAM_STR, 64 );
if ( $sth->execute() )
{
   $data = $sth->fetchAll( PDO::FETCH_ASSOC);
}

也许我错过了一些东西,但设置光标选项似乎有点毫无意义,如果你最终还是会这样做fetchAll()

于 2011-11-27T14:27:16.810 回答
0

准备和绑定参数是为了防止 sql 注入,
就像在发送到数据库之前转义变量一样,
而您的第二个查询对此没有任何防御。

于 2011-11-27T14:14:13.210 回答