PDO数据访问抽象层

PDO数据访问抽象层:

我们使用的mysqli是针对mysql这个数据库扩展的一个类,如果要用到别的数据库的话就可以用PDO来做

1.操作数据库

先来代码

<!--PDO-->
<!--数据访问抽象层-->
<!--可以访问其他数据库-->
<!--具有事务功能-->
<!--带有预处理语句功能(防止sql注入攻击功能)-->
<?php
//1.造PDO对象
$dsn = "mysql:dbname=heiheihei;host=localhost";
//冒号前面的是驱动名称(mysql),后面是参数:dbname=连接哪一个数据库;连接到本机
$pdo = new PDO($dsn,"root","12345678");
//root(数据库用户名,密码)

//2.写sql语句
$sql = "select * from mydb";
//查询语句


//3.执行sql语句
//$stm = $pdo->query($sql);
//执行查询语句


//4.从PDOStatement对象里面读取数据
//$arr = $stm->fetch(PDO::FETCH_ASSOC);
//返回关联数组,即返回一个索引为结果集列名的数组
//$arr = $stm->fetch(PDO::FETCH_BOTH);
//关联加索引,即返回一个索引为结果集列名和以0开始的列号的数组
//$arr = $stm->fetch(PDO::FETCH_NUM);
//返回索引的数组,即返回一个索引为以0开始的结果集列号的数组
//$arr = $stm->fetch(PDO::FETCH_OBJ);
//返回一个属性名对应结果集列名的匿名对象

//缺省为 PDO::ATTR_DEFAULT_FETCH_MODE 的值,即默认

//如果是PDOStatement::fetchAll,即代表一次性读出所有数据




var_dump($arr);
?>

输出:

调用一下fetch里面的参数为  PDO::FETCH_ASSOC

输出attr,则返回一个索引为结果集列名的数组:

调用一下fetch里面的参数为  PDO::FETCH_NUM

输出attr,则返回一个索引为结果集列名和以0开始的列号的数组:

调用一下fetch里面的参数为  PDO::FETCH_OBJ

输出attr,则返回一个属性名对应结果集列名的匿名对象:

改为fetchALL(PDO::FETCH_OBJ)也可以,它是把所有数据都可以查到:

用PDO来做个添加语句:

<?php
//1.造PDO对象
$dsn = "mysql:dbname=heiheihei;host=localhost";
//冒号前面的是驱动名称(mysql),后面是参数:dbname=连接哪一个数据库;连接到本机
$pdo = new PDO($dsn,"root","12345678");
//root(数据库用户名,密码)

//2.写sql语句

$sql = "insert into mydb VALUES ('虾','123','小虾',0)";
//增删改语句

//3.执行sql语句

$arr = $pdo->exec($sql);
//执行添加语句,exec返回影响的行数

//4.从PDOStatement对象里面读取数据
var_dump($arr);
?>

exec是用来执行其他语句,他返回的是受影响的行数

图:

显示了一个1,证明影响了1行数据;

如果失败了,运行后会显示0

再看一下,数据库内,已经添加成功:

 2.事务功能

事务功能即能够控制语句同时成功或同时失败,失败时可以回滚

事务有三个基本的方法:

PDO::beginTransaction() - 启动一个事务:将下面的代码看作一个事务

commit - 提交事务:是将开始和提交中间的代码看作一个事务一起执行提交

PDO::rollBack() - 回滚一个事务:如果有问题就回滚,没有问题就不用回滚,回滚就是还原

代码:

<?php
$dsn = "mysql:dbname = mydb;host=localhost";
//数据源
$pdo = new PDO($dsn,"root","123");
//造对象


//改事务模式

//1.将PDO的错误类型设为异常模式(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION )
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

//try尝试运行里面代码
try {
//开启事务
    $pdo->beginTransaction();

    $sql = "insert into mydb VALUES ('西','123','小西',0)";
    $sqll = "insert into mydb VALUES ('虾','123','小虾',0)";

    $pdo->exec($sql);
    $pdo->exec($sqll);

//提交事务
    $pdo->commit();
}

//catch抓住异常.控制异常。$e代表异常的数值
catch(Exception $e)
{
//    echo "有错误";

    //回滚操作!!!
    //如果发现有错误,回滚rollback!
    $pdo->rollBack();
}

//最终执行,必执行
//final
//{
   //无论有没有一场出现,该代码都会执行
//}
?>

在我的数据库里面帐号是主键

西是可以添加上的,但是虾有重复是加不上的,因为有事务功能 ,要么一起成功,要么一起失败,所以这两条数据都不会成功

运行完成,查看数据库:

 

果然一条都没有成功!

如果把虾改成对的:

 $sql = "insert into mydb VALUES ('西','123','小西',0)";
    $sqll = "insert into mydb VALUES ('东','123','小东',0)";

一起添加成功!!

 3.预处理语句防止SQL注入:

 他是分两次来发送到输出,就不会出现注入攻击了

(1)占位符“?”方法:

<?php


$dsn = "mysql:dbname=heiheihei;host=localhost";
$pdo = new PDO($dsn,"root","12345678");

//框架
$sql = "insert into mmaa VALUES (?,?)";
//写一个预处理语句,在写参数的地方用占位符“?”代替

    //将预处理语句扔到服务器等待执行,返回PDOStatomont对象;prepare准备,等待执行
$stm = $pdo->prepare($sql);

//第二次将变量(参数)扔到服务器的SQl语句相应位置,给预处理语句绑定参数。binparam绑定参数
//第一个参数第二个参数是
$stm->bindParam(1,$id);
$stm->bindParam(2,$name);

//赋值
$id = 5;
$name = "孙";
//执行
$stm->execute();

这是一个添加语句,让我们来看看添加成功

如果数据过多,上面这种方法会极其麻烦,所以还有一种简单方法

<?php


$dsn = "mysql:dbname=heiheihei;host=localhost";
$pdo = new PDO($dsn,"root","12345678");

//框架
$sql = "insert into mmaa VALUES (?,?)";
//写一个预处理语句,在写参数的地方用占位符“?”代替

    //将预处理语句扔到服务器等待执行,返回PDOStatomont对象;prepare准备,等待执行
$stm = $pdo->prepare($sql);


//定义一个数组,必须是索引数组
$arr = aarray("8","邵");

//执行
$stm->execute($arr);

这上面的这种方法很智能,并且很简便,它可以自动把参数仍到该扔到的地方

(2)名称占位法...

这种方法一目了然,知道该填什么参数

代码:

首先我设一个添加的页面:

<body>
<h1>添加一条数据</h1>
<form action="bbb.php" method="post">
<div>id:<input type="text" name="id"/></div>
    <div>姓名:<input type="text" name="name"/></div>
    <input type="submit" value="点击添加"/>
</form>

</body>

然后我去做处理页面:

<?php
$dsn = "mysql:dbname=heiheihei;host=localhost";
$pdo = new PDO($dsn,"root","12345678");

//预处理语句,括号里不是?了
$sql = "insert into mmaa VALUES (:id,:name)";
$stm = $pdo->prepare($sql);

//执行,$_post里面有id跟name的值,所以直接把post扔进去就好了
$stm->execute($_POST);

添加图:

点击添加,查看数据库:

添加成功了,代码量非常少

PDO常用方法及其应用

PDO::query() 主要是用于有记录结果返回的操作,特别是SELECT操作
PDO::exec() 主要是针对没有结果集合返回的操作,如INSERT、UPDATE等操作
PDO::prepare() 主要是预处理操作,需要通过$rs->execute()来执行预处理里面的SQL语句,这个方法可以绑定参数,功能比较强大(防止sql注入就靠这个)
PDO::lastInsertId() 返回上次插入操作,主键列类型是自增的最后的自增ID
PDOStatement::fetch() 是用来获取一条记录
PDOStatement::fetchAll() 是获取所有记录集到一个集合
PDOStatement::fetchColumn() 是获取结果指定第一条记录的某个字段,缺省是第一个字段
PDOStatement::rowCount() :主要是用于PDO::query()和PDO::prepare()进行DELETE、INSERT、UPDATE操作影响的结果集,对PDO::exec()方法和SELECT操作无效。

 防注入攻击原理:

当调用 prepare() 时,查询语句已经发送给了数据库服务器,此时只有占位符 ? 发送过去,没有用户提交的数据;当调用到 execute()时,用户提交过来的值才会传送给数据库,他们是分开传送的,两者独立的,SQL攻击者没有一点机会。

原文地址:https://www.cnblogs.com/xuan584521/p/6493160.html