PDO拓展

PDO提供了一套帮助用户实现多种数据库操作的统一接口
加载·
首先需要在php.ini文件加载需要使用的数据库拓展库 以mysql为例
去掉 ;exrtension =pdo_mysql前面的注释即可 然后重启apache就成功加载了
PDO
PDO主要由 PDO PDOStatement PDOException三个类组成
PDO PHP DATA OBECT 是一种纯面向对象的数据库操作拓展
PDO方法
构造函数 __construct($dsn,$user,$pass,$drivers);
$dsn : 驱动名字 例如 mysql
驱动选项 例如 localhost
端口 例如 3306
数据库名字 例如 test;
$user 用户名 例如 root
$pass 密码 例如 root
$drivers 驱动信息 例如更改PDO的报错模式(可不传入)
实例化:new Pdo("mysql:host =localhost;port=3306;dbname=syudyphp","root",980613);
写操作:exec(sql)返回一个受影响的行数 如果发生错误返回false
读操作query(sql);返回一个PDOStatement对象
利用pdostatement对象中的fetch()/fetchAll方法 可以得到返回的数组 通常传入参数PDO::MYSQL_ASSOC使输出关联数组
错误编号 errorcode返回当前操作的错误编号
错误信息 errorinfo返回一个索引数组 错误代码 驱动代码 错误信息

<?php 
#实例化PDO对象
$dsn = "mysql:host=localhost;port=3306;dbname=studyphp";
$user="root";
$pass="980613";
$p = @new PDO($dsn,$user,$pass);//返回一个PDO对象
 #写操作
 $sql = "delete from student where id =7 ";
 $res = $p->exec($sql);
 var_dump($res);//int(1)
 #读操作
 $sql ="select*feom student";
 $statements = $p->query($sql);
 var_dump($p);//object(PDO)#1(0){}
;    ?>

是开发中通常对PDO进行二次封装
PDO能独立的完成写的操作

<?php 
   #注册认证函数
   function pdo_init(){
       $p = new PDO("mysql:host=localhost;port=3306;dbname=studyphp","root","980613");
       if(!$p){
           echo "连接认证失败".$p->errorInfo()[2];
           exit;
       }
       return $p;
   }
   #写操作
   function pdo_exec1($p,$sql){
       $res = $p->exec($sql);
       if($res===false){
           echo "数据库语句执行失败","<br/>";
           echo "错误代码为".$p->errorcode();
           echo "错误信息为".$p->errorInfo()[2];
       }
       return $res;
   }
   #读操作
   function pdo_query($p,$sql,$all=true){
       $s = $p->query($sql);
       if(!$s){
        echo "数据库语句执行失败","<br/>";
        echo "错误代码为".$p->errorcode();
        echo "错误信息为".$p->errorInfo()[2];
       }
       if($all){
           return $s->fetchAll(pdo::FETCH_ASSOC);
       }else{
           return $s->fetch(PDO::FETCH_ASSOC);
       }
   }
   #返回自增长 id
   function getId($p){
       return $p->lastInsertid();
       //返回当前插入的自增长id
   }
   #测试代码
   $p = pdo_init();
   $sql = "delete from student where id = 8";
   pdo_exec1($p,$sql);
   echo getId($p);
   $sql = "select * from student ";
   $res= pdo_query($p,$sql);
   echo "<pre/>";
   var_dump($res);
   /*0
array(3) {
  [0]=>
  array(3) {
    ["id"]=>
    string(1) "9"
    ["name"]=>
    string(3) "ada"
    ["age"]=>
    string(2) "10"
  }
  [1]=>
  array(3) {
    ["id"]=>
    string(2) "10"
    ["name"]=>
    string(3) "bob"
    ["age"]=>
    string(2) "12"
  }
  [2]=>
  array(3) {
    ["id"]=>
    string(2) "11"
    ["name"]=>
    string(5) "condy"
    ["age"]=>
    string(2) "13"
  }
}*/
   ?>

事务处理
PDO封装了一些提供失误处理的方法 当然本质上还是执行execsql语句
开启事务beginTransaction
执行代码
成功提交commit
失败回滚 rollback
设置回滚exec(savepoint sp1)
回到回滚点 exec(rollback to sp1)
PDOExceptio
不仅过设置的异常处理机制是一种所见即所得 对用户体验来说很不友好
Exception是面向对象中一种错误的捕捉机制
捕捉执行层的问题

getfile获得文件地址
getline异常行
<?php
set_error_handler(function(){
 throw new Exception("发生错误");
});
#告诉系统不要直接报错
try{
 echo $res = 4/0;//发生错误
}catch(Exception $e){
 echo  $e->getmessage();
}
?>

PDO有一个专门处理异常的类 PDOException
PDO有三种错误处理机制 分别是
PDO::ERRMODE_SILENT 默认静默模式 不报错
PDO::ERRMODE_WARING 直接报错
PDO::ERRMODE_EXCEPTION 异常处理模式 处理异常

<?php
try{
  $p = new PDO("mysql:host=localhost;port=3306;dbname=studyphp","root",980613); 
  if(!$p){
    throw new Exception("连接认证失败");
  }
}catch(Exception $e){
  #由于用户传入数据而产生的不可意料的错误 要抓取
  echo "sql连接出错","<br/>";
  echo $e->getMessage(),"<br/>";
}
$p->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
#更改模式
#异常处理函数
function getException($pdo,$sql){
  try{
    $res = $pdo->exec($sql);
    //可以在编写代码时就可以意料到的错误可以主动抛出
    if(!$res){
      throw new  Exception("sql语句执行错误");
    }
  }catch(Exception $e){
    #由于用户传入数据而产生的不可意料的错误 要抓取
    echo "sql语句出错","<br/>";
    echo $e->getMessage(),"<br/>";
  }
}
$sql = "update student set age =88 where id = 10";
getException($p,$sql);
?>

总之来说在编码时可以预见的错误就经判断后主动抛出throw new Exceprion(错误信息)
然后由于客户操作而不可预知的错误由系统抓取 getMessage可以获得上面的错误信息
预处理
当sql语句重复性比较大时 预处理机制可以提高效率
prepare提交预处理代码 一般里面都会有占位符才有意义
execute执行预处理代码 一般都会用到use给占位符赋值才有意义 use后必须是个变量
drop删除预处理
在这里插入图片描述
prepare 预处理名字 from '预处理语句';
PDO本身提供了一套预处理机制
prepare()参数为sql语句 成功返回PDOStatement 对象 失败返回false
bindvlaue第一个参数为占位符 ?/:name 后者不要考虑先后顺序 第二个参数是变量的值 或者另一个变量 此方法的传入的即使是变量 也只是获得变量的值 以后变量改变也不会影响值
bindparam第一个参数为占位符 第二个参数必须为变量引用 引用传递
```execute``执行 如果执行语句时查询 结果会返回到对象之中

<?php
#准备sql语句
$p = new PDO("mysql:host=localhost;port=3306;dbname=studyphp","root",980613);
$sql = "select *from student where id between :min and :max "; //:name 的形式相当于?不用考虑位置的问题
#发送预处理
$s = $p->prepare($sql);
#绑定预处理参数
$s->bindValue(':min',9);
$s->bindValue(':max',14);
#执行预处理
$s->execute();
echo "<pre/>";
$res = $s->fetchAll(PDO::FETCH_ASSOC);
var_dump($res);
?>

PDO二次封装
二次封装 简化操作 提高用户体验

<?php
#二次封装PDO 
#核心类
namespace core;
#把全局空间的类引入进来
use \PDO,\PDOStatement,\PDOException;
use Exception;

class Dao{
  #PDO对象会经常在其他方法中使用 封装一个函数、
  private $pdo;
  private $fetch_mode;
  public function __construct($info=array(),$drivers=array()){
        $type = $info['type'] ?? 'mysql';
        $host = $info['host'] ?? "localhost";
        $port = $info['port'] ?? '3306';
        $dbname = $info['dbname'] ?? 'studyphp';
        $user = $info['user'] ?? 'root';
        $pass = $info['pass'] ?? '980613';
        $charset = $info['charset'] ?? 'utf8';
        $this->fetch_mode=$info['fetch_mode'] ?? PDO::FETCH_ASSOC;
        $driver['PDO::ATTR_ERRMODE'] = $drivers['PDO::ATTR_ERRMODE'] ?? 'PDO::ERRMODE_EXCEPTIOPN';
        $dsn = $type.':'.'host='.$host.';port='.$port.';dbname='.$dbname;
        #实例化时候传入两个数组 也可以不传
        #第一个数组包含各种数据库信息 type host port dbname user pass charset fetch_mode
        #第二个数组传入驱动信息
        #实例化
        try{
          $this->pdo = new PDO($dsn,$user,$pass,$driver);
        }catch(Exception  $e){
            echo "对不起 连接认证失败";
            exit;
        }
        #设置字符集
        try{
          $this->pdo->exec("set names {$charset}");
        }catch(Exception $e){
          echo "对不起 设置字符集出错";
          exit;
        } 
   }
   #执行写操作
   public function dao_exec($sql){
     try{
       $row =$this->pdo->exec($sql);
       return $row ; //返回受影响行数
     }catch(Exception $e){
       echo "对不起 sql语句执行错误","<br/>";
       echo $e->getMessage();
       exit;
     }
   }
   #获取自增长id 
   public function getlastid(){
     return $this->pdo->lastInsertId();
   }
   #读操作
   public function dao_query($sql,$all=true){
     try{
       $stam = $this->pdo->query($sql);
     }catch(Exception $e){
       echo "对不起  查询数据失败";
     }
     if($all){
       return $stam->fetchAll($this->fetch_mode);
     }else{
       return $stam->fetch($this->fetch_mode);
     }
   }
}
$d = new Dao();
/*$sql = "insert into student values(4,'ses',56)";
$d->dao_exec($sql);
echo $d->getlastid();*/
$sql = "select * from student";
$res = $d->dao_query($sql,FALSE);
echo "<pre/>";
var_dump($res);
?>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值