Heim > Backend-Entwicklung > PHP-Tutorial > 关于PDO防sql注入问题

关于PDO防sql注入问题

WBOY
Freigeben: 2016-06-06 20:42:23
Original
1112 Leute haben es durchsucht

在php编写程序中,我们可以使用类似如下的PDO预处理绑定语句来有效的防止sql注入问题:

<code>$stmt  =  $dbh -> prepare ( "INSERT INTO REGISTRY (name, value) VALUES (:name, :value)" );
$stmt -> bindParam ( ':name' ,  $name );
$stmt -> bindParam ( ':value' ,  $value );
$name  =  'one' ;
$value  =  1 ;
$stmt -> execute ();
</code>
Nach dem Login kopieren
Nach dem Login kopieren

或者使用?号占位符来达到相同的效果:

<code>$stmt  =  $dbh -> prepare ( "INSERT INTO REGISTRY (name, value) VALUES (?, ?)" );
</code>
Nach dem Login kopieren
Nach dem Login kopieren

笔者有一点表示很不理解,就是在PDO底层是如何处理该sql语句的,可以这么有效的防止注入问题。

请大家指点一下...thanks

回复内容:

在php编写程序中,我们可以使用类似如下的PDO预处理绑定语句来有效的防止sql注入问题:

<code>$stmt  =  $dbh -> prepare ( "INSERT INTO REGISTRY (name, value) VALUES (:name, :value)" );
$stmt -> bindParam ( ':name' ,  $name );
$stmt -> bindParam ( ':value' ,  $value );
$name  =  'one' ;
$value  =  1 ;
$stmt -> execute ();
</code>
Nach dem Login kopieren
Nach dem Login kopieren

或者使用?号占位符来达到相同的效果:

<code>$stmt  =  $dbh -> prepare ( "INSERT INTO REGISTRY (name, value) VALUES (?, ?)" );
</code>
Nach dem Login kopieren
Nach dem Login kopieren

笔者有一点表示很不理解,就是在PDO底层是如何处理该sql语句的,可以这么有效的防止注入问题。

请大家指点一下...thanks

大部分常见数据库都支持prepare语句,以postgresql为例

<code>PREPARE fooplan (int, text, bool, numeric) AS
    INSERT INTO foo VALUES($1, $2, $3, $4);

EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
</code>
Nach dem Login kopieren

第一句把insert prepare成为名为fooplan的statement,第二句用具体的数据去execute fooplan statement

注意,fooplan是当前数据库连接中有效的,另一个数据库连接就不能直接execute fooplan

在数据库支持prepare特性的情况下,PDO就使用数据库的prepare语句来实现

<code>$fooplan = $pdo->prepare('INSERT INTO foo VALUES(?, ?, ?, ?)');
$fooplan->execute(array(1, 'Hunter Valley', 't', 200.00));
</code>
Nach dem Login kopieren

和sql对照一看是不是就明白了

因为prepare ... execute这个特性实在太有用,所以即使数据库不支持prepare,pdo也会采用模拟的方式来实现,简单来说就是pdo自己对数据做quote,然后把结果拼接成sql再执行

还有一种特殊情况就是连接池,比如我用pgbouncer做postgresql连接池,连接池是transaction或statement模式。在这个模式下,每条语句都可能使用的不同的连接

所以pdo就没法使用到数据库的prepare特性,因为prepare和execute两条语句可能使用不同的连接,在这种情况下就必须强制使用pdo的模拟prepare方式才行

<code>$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
</code>
Nach dem Login kopieren

之前学参数化查询的时候看过的一篇Blog 供题主参考
参数化查询为什么能够防止SQL注入- LoveJenny - 博客园

对每个 pram 运行 PDO:quote.

http://php.net/manual/zh/pdo.quote.php

@runner_sam 你的推荐博客确实值得参考,而且分析的也很详尽,不失为一篇好的博客文章,谢谢你了。
这里笔者再推荐一篇文章,说明了PDO防注入原理分析以及使用PDO的注意事项,特此推荐给大家,仅供参考,共同进步...

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage