PDO(PHP Data Object),Mysqli,以及对sql注入等问题的解决
这篇是上一篇 http://www.cnblogs.com/charlesblc/p/5987951.html 的续集。
看有的文章提到mysqli和PDO都支持多重查询,所以下面的url会造成表数据被删。
http://localhost:8080/test.php?id=3;delete%20from%20users
可是我在mysql版本的函数,上面的sql都不能执行。是不是不支持多重查询了?
这篇文章 http://www.runoob.com/php/php-mysql-connect.html 对mysqli, PDO的方式有一些介绍,不详细。
主要用的这篇文章:http://blog.csdn.net/yipiankongbai/article/details/17277477
三种连接方式:
// PDO
$pdo = new PDO("mysql:host=localhost;dbname=database", 'username', 'password'); // mysqli, procedural way
$mysqli = mysqli_connect('localhost','username','password','database'); // mysqli, object oriented way
$mysqli = new mysqli('localhost','username','password','database');
先看mysqli过程型:
<?php
header('Content-Type: text/html; charset=utf-8');
echo "PHP version:" . PHP_VERSION . "<br/>"; $con = mysqli_connect('10.117.146.21:8306', 'root', '[password]');
mysqli_select_db($con, 'springdemo'); $input_id = trim($_GET['id']);
$sql = 'select nickname from user where id = ' . $input_id;
print_r('SQL is:' . $sql . '<br/>');
$result = mysqli_query($con, $sql); if ($result != null) {
print_r('rows:' . mysqli_num_rows($result) . '<br/>');
while ($row = mysqli_fetch_array($result)) {
print_r($row['nickname'] . '<br/>');
}
} mysqli_close($con);
?>
测试:
http://localhost:8080/test.php?id=3 PHP version:5.5.30
SQL is:select nickname from user where id = 3
rows:1
micro http://localhost:8080/test.php?id=3%20or%201=1 PHP version:5.5.30
SQL is:select nickname from user where id = 3 or 1=1
rows:4
abc
micro
helloworld
你好
加上real_escape函数:
?php
header('Content-Type: text/html; charset=utf-8');
echo "PHP version:" . PHP_VERSION . "<br/>"; $con = mysqli_connect('10.117.146.21:8306', 'root', '[password]');
mysqli_select_db($con, 'springdemo'); $input_id = mysqli_real_escape_string($con, $_GET['id']);
$sql = 'select nickname from user where id = ' . $input_id;
print_r('SQL is:' . $sql . '<br/>');
$result = mysqli_query($con, $sql); if ($result != null) {
print_r('rows:' . mysqli_num_rows($result) . '<br/>');
while ($row = mysqli_fetch_array($result)) {
print_r($row['nickname'] . '<br/>');
}
} mysqli_close($con);
?>
测试:
http://localhost:8080/test.php?id=3%20or%201=1 PHP version:5.5.30
SQL is:select nickname from user where id = 3 or 1=1
rows:4
abc
micro
helloworld
你好 注:仍然有问题,因为没有在url里面加引号!
采用推荐的mysqli的PreparedStatement方式:
?php
header('Content-Type: text/html; charset=utf-8');
echo "PHP version:" . PHP_VERSION . "<br/>"; $con = new mysqli('10.117.146.21:8306', 'root', '[password]', 'springdemo');
//mysqli_select_db($con, 'springdemo'); $query = $con->prepare('SELECT nickname FROM user WHERE id = ?');
$query->bind_param('s', $_GET['id']);
$query->execute(); $result = $query->get_result();
if ($result != null) {
print_r('rows:' . mysqli_num_rows($result) . '<br/>');
while ($row = mysqli_fetch_array($result)) {
print_r($row['nickname'] . '<br/>');
}
} mysqli_close($con);
?>
测试:
http://localhost:8080/test.php?id=3 PHP version:5.5.30
rows:1
micro http://localhost:8080/test.php?id=3%20or%201=1 PHP version:5.5.30
rows:1
micro
PDO与mysqli的对比:
性能
PDO和MySQLi都有非常好的性能。在非prepared statements的基准测试下,MySQLi略快2.5%,而prepared statements下是6.5%,可以说对于性能无关紧要。
PDO | MySQLi | |
Database support | 12 different drivers | MySQL only |
API | OOP | OOP + procedural |
Connection | Easy | Easy |
Named parameters | Yes | No |
Object mapping | Yes | Yes |
Prepared statements (client side) |
Yes | No |
Performance | Fast | Fast |
Stored procedures | Yes | Yes |
PDO方式:
<?php
header('Content-Type: text/html; charset=utf-8');
echo "PHP version:" . PHP_VERSION . "<br/>"; $pdo = new PDO("mysql:host=10.117.146.21:8306;dbname=springdemo", 'root', '[password]'); class Name {
public $nickname; public function info()
{
return '#'.$this->nickname;
}
} $input_id = $_GET['id'];
$sql = 'select nickname from user where id = ' . $input_id;
print_r('SQL is:' . $sql . '<br/>');
$result = $pdo->query($sql);
$result->setFetchMode(PDO::FETCH_CLASS, 'Name'); if ($result != null) {
while ($row = $result->fetch()) {
print_r($row->info() . '<br/>');
}
} $pdo=null;
?>
测试:
http://localhost:8080/test.php?id=3 PHP version:5.5.30
SQL is:select nickname from user where id = 3
#micro http://localhost:8080/test.php?id=3%20or%201=1 PHP version:5.5.30
SQL is:select nickname from user where id = 3 or 1=1
#abc
#micro
#helloworld
#你好
加上转码:
$input_id = $pdo->quote($_GET['id']);
测试:
http://localhost:8080/test.php?id=3 PHP version:5.5.30
SQL is:select nickname from user where id = '3'
#micro http://localhost:8080/test.php?id=3%20or%201=1 PHP version:5.5.30
SQL is:select nickname from user where id = '3 or 1=1'
#micro
注意,pdo的quote自动加了引号,解决了这个问题。
http://localhost:8080/test.php?id=3%27%20or%201=%271 PHP version:5.5.30
SQL is:select nickname from user where id = '3\' or 1=\'1'
#micro
并且,尝试自己加引号去做侵入也没有用的。引号被转码了,所以成功防住攻击。
PDO的prepared statement:
<?php
header('Content-Type: text/html; charset=utf-8');
echo "PHP version:" . PHP_VERSION . "<br/>"; $pdo = new PDO("mysql:host=10.117.146.21:8306;dbname=springdemo", 'root', '[password]'); $prepared = $pdo->prepare('select nickname from user where id = :id'); $prepared->execute(array(':id' => $_GET['id'])); while ($results = $prepared->fetch(PDO::FETCH_ASSOC)) {
print_r($results['nickname'] . '<br/>');
} $pdo=null;
?>
实验:
http://localhost:8080/test.php?id=3 PHP version:5.5.30
micro http://localhost:8080/test.php?id=3%20or%201=1 PHP version:5.5.30
micro
都不再出现sql注入的威胁。
PDO里面多次用到fetch:
值 | 说明 |
---|---|
PDO::FETCH_ASSOC | 关联数组形式。 |
PDO::FETCH_NUM | 数字索引数组形式。 |
PDO::FETCH_BOTH | 两者数组形式都有,这是默认的。 |
PDO::FETCH_OBJ | 按照对象的形式,类似于以前的mysql_fetch_object()函数。 |
PDO::FETCH_BOUND | 以布尔值的形式返回结果,同时将获取的列值赋给bindParam()方法中指定的变量。 |
PDO::FETCH_LAZY | 以关联数组、数字索引数组和对象3种形式返回结果。 |
把上面程序给prepared statement传参数的过程改了一下:
<?php
header('Content-Type: text/html; charset=utf-8');
echo "PHP version:" . PHP_VERSION . "<br/>"; $pdo = new PDO("mysql:host=10.117.146.21:8306;dbname=springdemo", 'root', '[password]'); $prepared = $pdo->prepare('select nickname from user where id = :id'); $prepared->bindParam(':id', $_GET['id']);
$prepared->execute(); while ($results = $prepared->fetch(PDO::FETCH_ASSOC)) {
print_r($results['nickname'] . '<br/>');
} $pdo=null;
?>
实验之后,结果对于上面哪些url,都能得到正确的结果。
性能方面:
PDO和MySQLi都有非常好的性能。在非prepared statements的基准测试下,MySQLi略快2.5%,而prepared statements下是6.5%,可以说对于性能无关紧要。
如果你真的非常介意这一点点性能的话,而自带的MySQL扩展比两者都快,你可以考虑下它。
上面部分来自这篇:http://blog.csdn.net/yipiankongbai/article/details/17277477 《PDO vs. MySQLi 选择哪一个?》
PDO(PHP Data Object),Mysqli,以及对sql注入等问题的解决的更多相关文章
- PDO(PHP Data Object)数据访问抽象层
1.可以访问其它数据库2.具有事务功能3.带有预处理语句功能(防止SQL注入攻击) 访问数据库 PDO::__construct ( string $dsn [, string $username [ ...
- Java学习笔记47(JDBC、SQL注入攻击原理以及解决)
JDBC:java的数据库连接 JDBC本质是一套API,由开发公司定义的类和接口 这里使用mysql驱动,是一套类库,实现了接口 驱动程序类库,实现接口重写方法,由驱动程序操作数据库 JDBC操作步 ...
- 关于SQL注入的问题以及解决方法
1.关于SQL注入 什么是SQL注入: 由于jdbc程序在执行的过程中sql语句在拼装时使用了由页面传入参数,如果用户恶意传入一些sql中的特殊关键字,会导致sql语句意义发生变化,这种攻击方式就叫做 ...
- SQL注入实验,PHP连接数据库,Mysql查看binlog,PreparedStatement,mysqli, PDO
看到有人说了判断能否sql注入的方法: 简单的在参数后边加一个单引号,就可以快速判断是否可以进行SQL注入,这个百试百灵,如果有漏洞的话,一般会报错. 下面内容参考了这两篇文章 http://blog ...
- PDO 学习与使用 ( 一 ) :PDO 对象、exec 方法、query 方法与防 SQL 注入
1.安装 PDO 数据库抽象层 PDO - PHP Data Object 扩展类库为 PHP 访问数据库定义了一个轻量级的.一致性的接口,它提供了一个数据访问抽象层,针对不同的数据库服务器使用特定的 ...
- 如何使用PDO查询Mysql来避免SQL注入风险?ThinkPHP 3.1中的SQL注入漏洞分析!
当我们使用传统的 mysql_connect .mysql_query方法来连接查询数据库时,如果过滤不严,就有SQL注入风险,导致网站被攻击,失去控制.虽然可以用mysql_real_escape_ ...
- SQL注入之代码层防御
[目录] 0x0 前言 0x1 领域驱动的安全 1.1 领域驱动的设计 1.2 领域驱动的安全示例 0x2 使用参数化查询 2.1 参数化查询 2.2 Java中的参数化语句 2.3 .NET(C#) ...
- sql注入实例分析
什么是SQL注入攻击?引用百度百科的解释: sql注入_百度百科: 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具 ...
- jdbc操作数据库以及防止sql注入
public class pr { public static void main(String[] args) { Connection conn = null; Statement st = nu ...
随机推荐
- shell 运算
一个下午折腾一个脚本,shell好久不用,重新学起 一个小成果 size= ] do table=albums_index_${table_num} count=$size times= while ...
- 说说php取余运算(%)的那点事
http://www.phpddt.com/php/php-take-over.html fmod()与 % 区别 都是取余 fmod是函数 原型float fmod(float x, ...
- sao/jsp
sao/i18n/message/ Messages-Client.xml Messages-Server.xml sao/wsdl Verification.wsdl IProcessS ...
- web服务器 应用 服务器
WEB服务器.应用程序服务器.HTTP服务器有何区别?IIS.Apache.Tomcat.Weblogic.WebSphere都各属于哪种服务器,这些问题困惑了很久,今天终于梳理清楚了: Web服务器 ...
- https://google-developers.appspot.com/chart/
https://google-developers.appspot.com/chart/
- 2015年4月 非常干货之Python资源大全
[非常干货之Python资源大全]Python是一门美妙的语言,简单易用,容易提升.它是一门主流语言,却没有其它专业语言的弊病,从游戏,ML,GUI到科学和数学有着巨量的函数库. 直击现场 <H ...
- 《Thinking in C++》学习笔记(一)【第二章】
第二章 对象的创建与使用 2.1语言的翻译过程 翻译器分为两类:解释器(interpreter)和编译器(compiler). 2.1.1解释器 解释器将源代码转化成一些动作(它可由许多机器指令组成) ...
- java理论基础学习一
java的最大优势是跨平台 java的版本和体系架构 1.J2EE Java 2 Enterprise Edition 定位在服务器端的应用 2.J2SE Java 2 Standard Ed ...
- nil和NULL
- 使用CSS3制作漂亮的按钮
我给大家介绍一下如何使用CSS3来制作一个圆角阴影.渐变色的漂亮的按钮,它不需要任何图片和javascript脚本,只需要CSS3就可以轻松实现按钮效果,并且可以适用于任意HTML元素,想div,sp ...