2011-04-14 84 views
1

我已经完成了我的研究,并决定在我的查询中使用准备好的语句,我只是问是否有任何我应该知道的事情,关于切换到正常的mysqli查询以准备好语句的好坏。在正常的mysqli语句中使用预处理语句的优点?

此外,我不明白如何不需要转义坏字符的需要?

回答

5

转义坏字符仍然需要,但是库会自动为您绑定的所有参数自动执行。它只是稍微方便一些,并且可以防止程序员忘记清理值。

但是,请注意,此自动功能仅限于参数!

下面的查询是安全的,因为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(); 

表示,不应该使用如本例中所示的动态表名称。但是问题是:即使参数化查询也要小心!

我能想到的唯一不足就是你不能再看到最后的查询来进行调试(因为它只在服务器端进行组装)。

+0

按说逃逸仍然需要人品不好,我假定你的意思任何不会自动执行的字符? – Basic 2011-04-14 11:21:28

+0

@基本否,对于作为参数添加的常规数据,不需要任何额外的转义。图书馆将照顾一切。什么参数化查询*不能*处理是动态表和列名,但人们通常不应该使用那些摆在首位 – 2011-04-14 11:23:45

+0

@Pekka웃是能够制备表名? – 2014-03-19 21:13:07

1

至少有两个优点:

  • 没有进行转义值:它的自动完成
  • 的语句是(使用绑定的参数,当然,当)发送到SQL服务器,只准备一次;并且,然后,可以多次执行 - 这是伟大的表演(该语句解析只有一次,即使执行很多次)
+0

我总是有问题要问你的第二点 - >准备一次,多次执行的PHP文件相同的执行被限制或也适用于未来的执行 – 2016-03-30 05:49:42

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

大多数人会混淆准备好的语句和占位符。

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

占位符是伟大的,因为:

  • 他们是安全的,因为他们做了一切正确的格式
  • 它们更容易使用,因为它们自动执行所有正确的格式(不傻“逃跑”!)。
  • 它们很方便,因为它们只对正确进入查询的值进行所有正确的格式设置,而不对源变量进行格式设置。

至于大家都在谈论的性能问题,大部分时间准备语句比普通查询慢。然而,在这两种情况下,这种差异都是不明显的。