PHP PDO使用

PDO

概述

  • PDO是PHP数据对象(PHP Data Object)的缩写
  • PDO是一个第三方类,默认以集成到PHP中
  • 使用PDO可以轻松对接各种不同类型的数据库,且操作方式和方法调用都基本一样
  • PDO作用是统一各种数据库的访问接口

开启PDO扩展

开启mysql扩展为例

  • 前期:php文件中的ext文件夹中包含php_pdo_mysql.dll扩展文件
  • 修改php.ini文件,把extension = php_pdo_mysql.dll(extension=pdo_mysql)前的;去掉,然后重新启动php.exe程序(或重启apache);
  • 使用phpinfo()进行检查是否已启动PDO扩展

创建PDO类对象

  • 语法:PDO::__construct ( string d s n ‘ [ , s t r i n g ‘ dsn` [, string ` dsn[,stringusername[, string p a s s w o r d ‘ [ , a r r a y ‘ password` [, array ` password[,arraydriver_options]]] )

    • $dsn 数据源
    • $username 用户名
    • $password 密码
  • 代码实现

<?php
/* 创建一个连接mysql数据库的pdo对象 */
$dsn = 'mysql:dbname=testdb;host=127.0.0.1;charset=utf8';
$user = 'dbuser';
$password = 'dbpass';

try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

?>

PDO对象常用方法

PDO::exec()方法

  • 描述:执行一条sql语句,并返回受影响的行数(注意:select查询的sql语句,不会返回结果)
  • 语法:int PDO::exec(String $sql)
  • 参数:$sql 需要被预处理和执行的sql语句
  • 返回:返回被修改或删除的sql语句影响的行数,如果没有受影响的行,则返回0;
<?php
    //创建一个连接mysql数据库的PDO对象
    $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
    $user = 'root';
    $password = 'root';

    try{
        $pdo = new PDO($dsn,$user,$password);
        $sql = "INSERT INTO user (id,name,age,sex) VALUES(null,'xiaode',99,1)";
        $rel=$pdo->exec($sql);
        var_dump($rel);
    }catch(PDOException $e){
        echo "Connection faile:".$e->getMessage();
    }

PDO::query()方法

  • 描述:执行一条sql语句,返回一个结果集对象,一般用于select、show语句
  • 语法:public PDOStatemet PDO::query(String $statement)
  • 返回:执行成功返回PDOstatement对象,执行失败返回false;
<?php
    //创建一个连接mysql数据库的PDO对象
    $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
    $user = 'root';
    $password = 'root';

    try{
        $pdo = new PDO($dsn,$user,$password);
      
        //查询结果集
        $sql = "SELECT * FROM user ORDER BY id DESC";
        $rel = $pdo->query($sql);
        var_dump($rel);
		//输出结果
        //object(PDOStatement)#2 (1) { ["queryString"]=> string(35) "SELECT * FROM user ORDER BY id DESC" } 
     
    }catch(PDOException $e){
        echo "Connection faile:".$e->getMessage();
    }

PDO::lastInsertId()方法

  • 描述:返回最后插入的ID或序列值
  • 语法:String PDO::lastInsertId(void)
  • 返回值:最后出入行的ID
<?php
    //创建一个连接mysql数据库的PDO对象
    $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
    $user = 'root';
    $password = 'root';

    try{
        $pdo = new PDO($dsn,$user,$password);
        //插入语句
        $sql = "INSERT INTO user (id,name,age,sex) VALUES(null,'xiaode',99,1)";
        $rel=$pdo->exec($sql);

        //获取最后插入的id获取序列号
        $rel=$pdo->lastInsertId();
        var_dump($rel);//输出结果为4
    }catch(PDOException $e){
        echo "Connection faile:".$e->getMessage();
    }

PDO::setAttribute()方法

  • 描述:设置数据库句柄的属性

  • 语法:bool PDO::setAttribute(int $attribute,mixed $value)

  • 注意:PDO内置了以下可用的通用属性,使用参考 手册

    • PDO::ATTR_CASE 强制列名为指定的大小写
    • PDO::ATTR_ERRMODE 错误报告
    • PDO::ATTR_DEFAULT_FETDH_MODE 默认的提取模式
  • 返回值:成功返回true,失败返回false

<?php
    //创建一个连接mysql数据库的PDO对象
    $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
    $user = 'root';
    $password = 'root';

    try{
        $pdo = new PDO($dsn,$user,$password);

        //设置PDO属性 设置从结果集中提取值 FETCH_ASSOC为关联数组 FETCH_NUM枚举
        $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);

        //查询结果集
        $sql = "SELECT * FROM user ORDER BY id DESC";
        $rel = $pdo->query($sql);
        //遍历结果集
        foreach($rel as $v){
            echo "<pre>";
            var_dump($v);
        }
    }catch(PDOException $e){
        echo "Connection faile:".$e->getMessage();
    }

输出结果如下:

array(4) {
  ["id"]=>
  string(1) "4"
  ["name"]=>
  string(6) "xiaode"
  ["age"]=>
  string(2) "99"
  ["sex"]=>
  string(1) "1"
}

PDO预处理

预处理过程

  • sql语句执行分两个阶段,编译和执行
  • 第一次执行sql语句,需要先编译,编译过程复杂和耗系统资源,相对不安全
  • 同一条sql语句执行,直接从缓存中读取执行,效率提高,也比较安全,从而避免sql注入等安全问题

预处理步骤

  • PDO完成预处里需要的步骤
    • 提取相同结构的sql部分(把数据部分,可变部分进行去除)
    • 编译相同的结构,并把编译结果保存
    • 把不同的数据部分进行替换
    • 执行sql
  • 提取相同结构的sql语句
    • 在sql语句中,使用命名参数和问号参数,来代替可变的数据
    • 使用占位符“:value"和"?"来代替可变的数据

预编译方法

  • 描述: 准备要执行的语句,并返回语句对象
  • 语法: public PDO::prepare ( string $statement [, array $driver_options = array() ] )
  • 参数:需要预处理的sql语句

给占位符绑定数据

  • 描述:绑定一个值到预处理的sql语句中对应的命名占位符或问好占位符。
  • 语法:bool PDOStatement::bindValue(mixed $parmeter,mixed $value);
    • parameter,参数标识符,对应命名占位符的预处理语句,应该是类似:name形式的参数名,对于问号占位符的预处理语句,应该是以1开始的索引参数位置
    • $value ,绑定的参数值
  • 返回值:成功返回true 失败返回false

执行预处理的sql语句

  • 描述:执行一条预处理的语句
  • 语法:bool PDOStatement::execute()
  • 返回:成功返回true,失败返回false

示例1:使用命名参数方式示例

<?php
    //创建一个连接mysql数据库的PDO对象
    $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
    $user = 'root';
    $password = 'root';

    try{
        $pdo = new PDO($dsn,$user,$password);
        //设置异常捕捉
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        
        //使用命名参数进行绑定
        $sql = "INSERT INTO user(name,age,sex) VALUES(:name,:age,:sex)";

        //对内容进行预编译
        $stmt = $pdo->prepare($sql);

        //对占位数据进行绑定
        $stmt->bindValue(':name','rufeike');
        $stmt->bindValue(':age',30);
        $stmt->bindValue(':sex',0);

        //执行已预编译的sql
        $rel=$stmt->execute();

        //获取最后插入的id
        $id=$pdo->lastInsertId();
        var_dump($id);

    }catch(PDOException $e){
        echo "Connection faile:".$e->getMessage();
        echo "错误编号:".$e->getCode();
        echo "错误行号:".$e->getLine();
    }

示例2:使用问号参数绑定

<?php
    //创建一个连接mysql数据库的PDO对象
    $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
    $user = 'root';
    $password = 'root';

    try{
        $pdo = new PDO($dsn,$user,$password);
        //设置异常捕捉
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

        //使用问号参数绑定方式
        $sql = "INSERT INTO user(name,age,sex) VALUES(?,?,?)";

        //对sql语句进行预编译
        $stmt = $pdo->prepare($sql);

        //对占位符进行数据绑定
        $stmt->bindValue(1,'如非客2');
        $stmt->bindValue(2,28);
        $stmt->bindValue(3,1);

        //执行已编译的sql
        $rel = $stmt->execute();

        //获取最后出入的主键
        $id = $pdo->lastInsertId();
        var_dump($id);


    }catch(PDOException $e){
        echo "Connection faile:".$e->getMessage();
        echo "错误编号:".$e->getCode();
        echo "错误行号:".$e->getLine();
    }

从结果集提取数据

PDOStatement::fetch()方法

  • 描述:从结果集中获取一行,并向下移动指针
  • 语法:mixed PDOStatement::fetch([int $fetch_style])
    • PDO::FETCH_ASSOC,返回一个索引为关联数组的结果值
    • PDO::FETCH_BOTH(默认),返回一个包含索引为0开始的索引数组和关联数组
    • PDO::FETCH_NUM,返回一个索引以0开始的结果集数组
<?php
    //创建一个连接mysql数据库的PDO对象
    $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
    $user = 'root';
    $password = 'root';

    try{
        $pdo = new PDO($dsn,$user,$password);
        $sql = "SELECT * FROM user ORDER BY id DESC";
        $stmt = $pdo->query($sql);
        //每次从结果集中提取一行数据
        while($rel=$stmt->fetch(PDO::FETCH_ASSOC)){
            echo "<pre>";
            var_dump($rel);
        }
    }catch(PDOException $e){
        echo "Connection faile:".$e->getMessage();
    }

结果输出

array(4) {
  ["id"]=>
  string(1) "4"
  ["name"]=>
  string(6) "xiaode"
  ["age"]=>
  string(2) "99"
  ["sex"]=>
  string(1) "1"
}
array(4) {
  ["id"]=>
  string(1) "3"
  ["name"]=>
  string(6) "xiaode"
  ["age"]=>
  string(2) "99"
  ["sex"]=>
  string(1) "1"
}

PDOStatement::fetchAll()方法

  • 描述:返回一个包含结果集中所有行的数组
  • 语法:array PDOStatement::fetchAll([int $fetch_style])
    • PDO::FETCH_ASSOC,返回一个索引为关联数组的结果值
    • PDO::FETCH_BOTH(默认),返回一个包含索引为0开始的索引数组和关联数组
    • PDO::FETCH_NUM,返回一个索引以0开始的结果集数组
<?php
    //创建一个连接mysql数据库的PDO对象
    $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
    $user = 'root';
    $password = 'root';

    try{
        $pdo = new PDO($dsn,$user,$password);
        $sql = "SELECT * FROM user ORDER BY id DESC";
        $stmt = $pdo->query($sql);

        //一次性全部取出
        $rel=$stmt->fetchAll(PDO::FETCH_ASSOC);
        echo "<pre>";
        var_dump($rel);

    }catch(PDOException $e){
        echo "Connection faile:".$e->getMessage();
    }

输出结果

array(4) {
  [0]=>
  array(4) {
    ["id"]=>
    string(1) "4"
    ["name"]=>
    string(6) "xiaode"
    ["age"]=>
    string(2) "99"
    ["sex"]=>
    string(1) "1"
  }
  [1]=>
  array(4) {
    ["id"]=>
    string(1) "3"
    ["name"]=>
    string(6) "xiaode"
    ["age"]=>
    string(2) "99"
    ["sex"]=>
    string(1) "1"
  }

}

PDOStatement::rowCount()方法

  • 描述:返回上一个sql语句影响的行数
  • 语法:int PDOStatem::rowCount(void)
  • 返回值:返回上一个由对应的PDOStatement 对象执行 select、delete 、insert或update语句受影响的行数
  • 前提:需要使用PDO::query() 返回的PDOStatement对象
<?php
    //创建一个连接mysql数据库的PDO对象
    $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
    $user = 'root';
    $password = 'root';

    try{
        $pdo = new PDO($dsn,$user,$password);
        //获取查询结果集数
        $sql = "SELECT * FROM user ORDER BY id DESC";
        $stmt = $pdo->query($sql);
        $count=$stmt->rowCount();
        var_dump($count);
    }catch(PDOException $e){
        echo "Connection faile:".$e->getMessage();
    }

输出结果:

int(4)

PDO错误处理

静默模式

  • 静默模式:错误发生后,不会主动报错

    • 可以通过PDO::erroCode和PDO::errorInfo()两个方法获取
    • 默认为静默模式
    <?php
        //创建一个连接mysql数据库的PDO对象
        $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
        $user = 'root';
        $password = 'root';
    
        try{
            $pdo = new PDO($dsn,$user,$password);
    		//静默模式下获取错误信息
            $sql = "SELECT * FROM user WHERE abc = 'abc'";
            $stmt = $pdo->query($sql);
            echo "查询错误编号:".$pdo->errorCode();
            echo "查询错误信息:".print_r($pdo->errorInfo());
    
        }catch(PDOException $e){
            echo "Connection faile:".$e->getMessage();
        }
    
    

    错误信息打印结果:

    查询错误编号:42S22Array ( [0] => 42S22 [1] => 1054 [2] => Unknown column 'abc' in 'where clause' ) 查询错误信息:1
    

    没有错误是的打印结果 errorCode为00000时表示没有错误

    查询错误编号:00000Array ( [0] => 00000 [1] => [2] => ) 查询错误信息:1
    

警告模式

  • 警告模式:错误发生后,通过PHP标准来报错误

    • 设置错误模式为警告模式,错误结果根据php错误模式,直接在页面中输出
    • PDO::setAttribute(PDO::Attr_ERRMODE,PDO::ERRMODE_WARNING);
    • 这种方式不安全,会暴露系统相关信息
    <?php
        //创建一个连接mysql数据库的PDO对象
        $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
        $user = 'root';
        $password = 'root';
    
        try{
            $pdo = new PDO($dsn,$user,$password);
            //设置警告模式
            $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
    
    		//警告模式下获取错误信息 数据库中没有i字段
            $sql = "SELECT * FROM user WHERE i = 2";
            $stmt = $pdo->query($sql);
        }catch(PDOException $e){
            echo "Connection faile:".$e->getMessage();
        }
    
    

    错误打印结果

    Warning: PDO::query(): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'i' in 'where clause' in C:\Users\rufeike\Desktop\phasher\test\index.php on line 52
    

异常模式

  • 异常模式:错误发生后,抛出异常,需要捕捉和处理

    • 提示:可以通过PDO::setAttribute()更改模式
    <?php
        //创建一个连接mysql数据库的PDO对象
        $dsn = 'mysql:dbname=pdotest;host=127.0.0.1;charset=utf8';
        $user = 'root';
        $password = 'root';
    
        try{
            $pdo = new PDO($dsn,$user,$password);
            //设置异常模式
            $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    
    		//异常模式下获取错误信息
            $sql = "SELECT * FROM user WHERE i = 2";
            $stmt = $pdo->query($sql);
        }catch(PDOException $e){
            echo "Connection faile:".$e->getMessage();
            echo "错误编号:".$e->getCode();
            echo "错误行号:".$e->getLine();
        }
    
    

    错误打印结果

    Connection faile:SQLSTATE[42S22]: Column not found: 1054 Unknown column 'i' in 'where clause'错误编号:42S22错误行号:52
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值