在正常的mysqli语句中使用预准备语句的优点是什么?

时间:2011-04-14 11:12:07

标签: php mysqli

我已经完成了我的研究,并决定在我的查询中使用预准备语句,我要问是否有任何我应该知道的事情,无论是对正常的mysqli查询转换为准备好的语句都有好坏。

另外我不明白逻辑如何不需要转义坏字符?

4 个答案:

答案 0 :(得分:6)

仍然需要转义错误的字符,但是库会自动为您绑定的所有参数执行此操作。它只是稍微方便一点,并且阻止程序员忘记清理值。

但请注意,此自动操作仅限于参数!

以下查询是安全的,因为bind_param()负责转义:

$code = $_GET["code"];
$name= $_GET["name"];
$percentage= $_GET["percentage"];

$stmt = $mysqli->prepare("INSERT INTO items VALUES (?, ?, ?)");
$stmt->bind_param('iss', code, $name, $percentage);
$stmt->execute();

以下查询不安全,因为您直接放入查询的任何内容都不会自动转义

$tablename = $_GET["prefix"]."_items";  
$code = $_GET["code"];
$name= $_GET["name"];
$percentage= $_GET["percentage"];

                                    ---- UNSAFE! ----
$stmt = $mysqli->prepare("INSERT INTO `$tablename` VALUES (?, ?, ?)");
$stmt->bind_param('iss', $code, $name, $percentage);
$stmt->execute();

表示,不应该使用这个例子中显示的动态表名。但重点是:小心,即使是参数化查询!

我能想到的唯一缺点是你不能再看到最后的查询用于调试(因为它只在服务器端汇编)。

答案 1 :(得分:3)

至少有两个好处:

  • 不必处理转义值:它是自动完成的(当然使用绑定参数时)
  • 语句发送到SQL服务器,只准备一次;然后,可以多次执行 - 这对于表演非常有用(语句只解析一次,即使执行很多次)

答案 2 :(得分:2)

  1. 如果您使用带有占位符(?未命名,或:name已命名)的预准备语句,则会自动引用您插入的值。
  2. 预编译语句由dbms-engine预编译。因此查询只被解析一次,在以后的调用中它只是用值替换占位符。

答案 3 :(得分:2)

大多数人确实将准备好的陈述与占位符混为一谈。

使用占位符的一般想法非常好,而预处理语句只是功能有限的占位符的子集。

占位符很棒,因为:

  • 他们更安全,因为他们做了所有正确的格式化(不是愚蠢的“逃避”!)
  • 它们更易于使用,因为它们可以自动完成所有格式化。
  • 它们很方便,因为它们只对正确查询的值进行所有正确的格式化,而不是源变量。

至于每个人都在讨论的性能问题,大多数时间准备语句比常规查询慢。然而,在这两种情况下,差异都是不明显的。