PDO抽象层访问
以前接触的连接数据库的方法MYSQLi只能连mysql数据库,如果想连接其他数据库(比如Oracle,Access)就要通过加载php相关驱动的方式才能实现,所以我们就定义了一个PDO类来统一处理这个数据库连接方式。
第一步,造对象
1 $dsn = "mysql:dbname=mydb;host=localhost"; //数据库驱动和数据库的地址
2 $pdo = new PDO($dsn,"root","123"); 构建连接对象,其中包括了数据源,数据库用户名,数据库密码 (可以把上句的dsn直接写入这句)
第二步,写SQL语句
1 $sql = "select * from info";
第三步,执行SQL语句,返回PDOSTATEMENT对象
$stm = $pdo->query($sql); //如果是查询SQL语句,调用的是query()方法 $arr = $pdo->exec($sql); //如果是增删改语句,调用的是exec()方法
第四步,读取数据
1 $arr = $stm->fetch(PDO::FETCH_NUM); //读取一条数据,其中可以放入参数,PDO::FETCH_ASSOC表示关联数组,PDO::FETCH_NUM表示索引数组,PDO::FETCH_BOTH表示关联数组和索引数组一块显示。 2 //$arr = $stm->fetchAll(PDO::FETCH_ASSOC); //读取全部数据,里面的参数作用同上
2.pdo的事务功能,事务功能实际上就是遵循数据库范式,多个数据操作实现全部成功或全部失败,不存在中间情况,这样就保证了数据库的安全,比如取钱就可以避免扣款成功,但是并没有实现吐钞,网购支付时的扣款成功但是没有生成订单等异常情况。
建立好数据库连接后(上第一步)后,首先设置pdo属性为(异常模式)
1 $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
写运行语句(捕获异常)
1 try{ 2 $pdo->beginTransaction(); //事务开始 3 $sql="insert into student values ('133','dudu','男','1976-02-20 00:00:00','95888')"; 4 $sql2="insert into student values ('222','haha','女','1976-02-20 00:00:00','95666')"; 5 $pdo->exec($sql); 6 $pdo->exec($sql2); 7 8 $pdo->commit(); //事务提交 9 10 } 11 catch(Exception $e){ //捕获异常 12 13 $pdo->rollBack(); //事务回滚,就是回到事务开始前的状态 14 echo "出错了,所以数据回滚了"; 15 } 16 17 echo "执行成功";
3.pdo预处理功能(防止sql注入攻击)
1.用 ?占位 (绑定参数法)
1 $sql="insert into student values(?,?,?,?,?)"; 2 $stmt=$pdo->prepare($sql); //调用预处理方法 3 $stmt->bindParam(1,$Sno); //绑定参数,两个参数,第一个是预处理数据的位置,从1开始,第二个参数是个变量,变量的值就是要写入sql的相应数值 4 $stmt->bindParam(2,$Sname); 5 $stmt->bindParam(3,$Ssex); 6 $stmt->bindParam(4,$Sbrithday); 7 $stmt->bindParam(5,$Class); 8 $Sno="3333"; //给相应的变量赋值 9 $Sname="嘟嘟"; 10 $Ssex="女"; 11 $Sbirthday="1992-02-22 00:22:22"; 12 $Class="663333"; 13 $stmt->execute(); //执行方法
上面的方法有点麻烦,因为每次都要写那么多变量绑定和变量赋值,所以我们引入数组
2.同样是?占位,使用数组方便不少,代码如下 这种方法必须使用索引数组
1 <?php 2 3 4 $dsn = "mysql:dbname=mydb;host=localhost"; 5 $pdo = new PDO($dsn,"root","123"); 6 7 //预处理语句 8 $sql = "insert into nation values(?,?)"; 9 10 //将预处理语句发送到服务器等待执行,返回pdostatement对象 11 $stm = $pdo->prepare($sql); 12 13 14 $arr = array("n023","环境");//注意注意,这里是索引数组 15 16 //执行 17 $stm->execute($arr); 18 19 20 21 ?>
3.字符串的占位方式,这里使用的是索引数组,代码如下
1 <?php 2 $pdo=new PDO("mysql:dbname=test;host=localhost","root",""); 3 $sql="insert into student values(:Sno,:Sname,:Ssex,:Sbirthday,:Class)"; //每个字符串前面是 : 符号 4 $stmt=$pdo->prepare($sql); 5 $arr=array("Sno"=>"2222","Sname"=>"dududu","Ssex"=>"男","Sbirthday"=>"1993-03-22 00:00:01","Class"=>"033333"); //注意注意,这里是关联数组 6 $stmt->execute($arr);
4.说个例子,就是注册处理页面的预处理方式
<?php $dsn = "mysql:dbname=mydb;host=localhost"; $pdo = new PDO($dsn,"root","123"); $sql = "insert into nation values(:code,:name)"; //用了字符串的预处理方式 $stm = $pdo->prepare($sql); $stm->execute($_POST); //直接执行的POST方法(因为post方法的结果本身就是一个关联数组)