PHP对象进阶

110 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第32天,点击查看活动详情

PDO

数据库抽象层 PDO-PHP Data Object 扩展类库为 PHP 访问数据库定义了轻量级的一致性的接口,它提供了一个数据访问抽象层,针对不同数据库服务器使用特定的 PDO 驱动程序访问

image-20210204150053168

PDO:php5 以后的版本增加,是目前通用的 PHP 操作数据库的扩展

PDO 是一种纯面向对象的操作,有三个类

  • PDO 类:初始化和 SQL 执行
  • PDOStatement 类:结果解析
  • PDOException 类:异常处理

PDO 扩展

PDO 在 PHP5 以前,需要手动加载扩展

打开方法:

打开 PDO,PHP 配置文件 php.ini,将注释去掉即可

extension=php_pdo_mssql.dll

PDO 操作

常用方法

  • PDO::__construct

    实例化PDO对象,帮助实现连接认证,数据库选择,字符集设置

  • PDO::exec()

    执行一个写操作 SQL 指令,返回受影响的行数

  • PDO::query()

    执行一个读操作 SQL 指令,返回一个 PDOStatement 类对象(后者进行数据解析操作)

  • PDO::errorCode() 和 PDO::errorInfo()

    获取上次错误的信息(错误码和错误描述数组)

PDO实例化对象

利用其构造方法 __construct( string dsn,stringdsn , stringuser , string pass[,arraypass [ , array driver ] )

构造方法由4个参数组成,其中一般前三个为必选参数,第四个为可选参数

  1. $dsn(数据库基本信息)

    • 驱动名字(数据库产品),使用英文:分隔
    • 驱动选项(主机地址),使用host=具体主机地址,跟在驱动名字之后,如 'mysql:host=localhost'
    • 驱动选项(端口),使用 port=端口号,如是默认端口号则可以不写
    • 驱动选项(数据库名字),使用dbname=数据库名字(可不写)
    • 字符集设置(字符集名字),使用charset=字符集名字(可不写)
  2. $user

    用户名,如数据库允许匿名用户,则可以不写

  3. $pass

    同用户名,如数据库允许匿名用户,则可以不写

  4. $driver

    PDO 属性设置,是关联数组,利用 PDO 内部的常量进行设置

使用

<?php

$dsn='mysql:host=localhost;port=3306;dbname=test;charset=utf8;';
$user='root';
$pass='root';

$data=new PDO($dsn,$user,$pass);
var_dump($data);

# 输出
D:\phpstudy_pro\WWW\demo\mian.php:8:
object(PDO)[1]
    
    
$sql='delete news';
$data->exec($sql);
# 成功是1,不成功bool值false


$sql='select * from user';
$stmt=$data->query($sql);
var_dump($stmt);
# 查询成功返回一个 PDOStatement 对象
D:\phpstudy_pro\WWW\demo\mian.php:11:
object(PDOStatement)[2]
  public 'queryString' => string 'select * from user' (length=18)
    

#$sql='select * from user8';
#$stmt=$data->query($sql);   
if(false===$stmt){
    echo $data->errorCode().'<br>';
    var_dump($data->errorInfo());
    echo '<br>';
    echo $data->errorInfo()[2];
}    
# 输出
42S02
D:\phpstudy_pro\WWW\demo\mian.php:15:
array (size=3)
  0 => string '42S02' (length=5)
  1 => int 1146
  2 => string 'Table 'flask.user8' doesn't exist' (length=33)

Table 'flask.user8' doesn't exist

写操作

使用 PDO 实现数据库增删改操作

lastInsertId()获取最后增长的 id

......
$sql = "insert into admin values (null ,'user1',1233333)";
$stmt = $data->query($sql);

echo $data->lastInsertId();

# 获取每次 新增的 id 值

查询操作

  • PDO::query() 方法只能执行 SQL,不能直接解析结果,返回一个 PDOStatement 类对象

  • PDOStatement::fetch() 系列方法从对象中实现数据获取

    • fetch:获取一条记录
    • fetchAll:获取全部记录
  • FETCH_STYLE

    通过常量设计的方式实现获取数据的不同效果

<?php
function pdo_init()
{
    $dsn = 'mysql:host=localhost;port=3306;dbname=test;charset=utf8;';
    $user = 'root';
    $pass = 'root';
    $pdo = new PDO($dsn, $user, $pass);
    return $pdo;
}

function pdo_query($pdo, $sql)
{
    $stmt = $pdo->query($sql);
    return $stmt;
    # 返回一个 pdostatement 对象
}


function pdo_get($stmt, $only = ture, $fetch_style = PDO::FETCH_ASSOC)
{
    if (!$stmt instanceof PDOStatement) return false;
    if ($only) {
        return $stmt->fetch($fetch_style);
    } else {
        return $stmt->fetchAll($fetch_style);
    }
}

$sql = "select * from admin";

$pdo = pdo_init();
$stmt = pdo_query($pdo, $sql);
$data = pdo_get($stmt, false);
var_dump($data);

# 输出
D:\phpstudy_pro\WWW\demo\mian.php:35:
array (size=9)
  0 => 
    array (size=3)
      'uid' => string '1' (length=1)
      'name' => string 'admin' (length=5)
      'pass' => string '21232f297a57a5a743894a0e4a801fc3' (length=32)
  1 => 
    array (size=3)
      'uid' => string '2' (length=1)
      'name' => string 'user1' (length=5)
      'pass' => string '1233333' (length=7)
  2 => 
......

fetch_style 有很多

PDO 事务功能

将原来 MySQL 所支持的事务操作进行了一定的封装

事务执行是否成功由 MySQL 对应的存储引擎(InnoDB支持)是否支持

PDO 只是对具体的操作步骤进行了封装而已

  • PDO::beginTransaction()

    开启事务

  • PDO:exec()

    执行事务写操作

  • PDO::rollBack()

    回滚所有事物

  • PDO::commit()

    成功提交所有事物

事务主要用于一次连续执行多步指令

PDO 预处理

PDO 预处理:是 PDO 封装一套特定的方法,在方法中做了一些优化

  • PDO::prepare()

    发送预处理指令,只需要提供要执行的指令即可,不需要 prepare 名字 from,成功则得到一个 PDOStatement() 类对象,失败得到一个 false (或者异常错误)

  • PDOStatement::bindParam()

    绑定预处理所需要的参数,只能绑定变量(引用传递)

  • PDOStatement::bindValue()

    绑定预处理所需要的参数,可以绑定值(值传递)

  • PDOStatement::execute()

    执行预处理,成功返回 true ,失败返回 false

PDO 预处理本身实现了 MySQL 的预处理

优化了占位符:使用 :名字 代替 ?作为占位符(查看更加直观,内部还是 ?)

使用预处理,数据以变量进行拼接,防止 SQL 注入,更加安全

<?php
function pdo_init()
{
    $dsn = 'mysql:host=localhost;port=3306;dbname=test;charset=utf8;';
    $user = 'root';
    $pass = 'root';
    $pdo = new PDO($dsn, $user, $pass);
    return $pdo;
}

$pdo=pdo_init();

$pre_sql='select * from admin where uid=?';
$pre_sql='select * from admin where uid=:id';

// 发送预处理指令
$stmt=$pdo->prepare($pre_sql);

$id=4;
$stmt->bindValue(':id',1);
// 直接绑定数据
$stmt->bindValue(':id',$id);
# 绑定变量数据

$stmt->bindParam(':id',$id);
// 必须传递变量


$res = $stmt->execute();
# 如果结果为 true 说明执行了预处理,但是结果无法取出
# 需要使用 fetch 查处结果
$data=$stmt->fetchall(PDO::FETCH_ASSOC);
var_dump($data);

# 输出
D:\phpstudy_pro\WWW\demo\mian.php:34:
array (size=1)
  0 => 
    array (size=3)
      'uid' => string '4' (length=1)
      'name' => string 'user1' (length=5)
      'pass' => string '1233333' (length=7)

pdo 预处理绑定

结果 data=data=stmt->fetchall(PDO::FETCH_ASSOC); var_dump($data);

输出

D:\phpstudy_pro\WWW\demo\mian.php:34: array (size=1) 0 => array (size=3) 'uid' => string '4' (length=1) 'name' => string 'user1' (length=5) 'pass' => string '1233333' (length=7)


**pdo 预处理绑定**

![image-20210205101515721](https://img-blog.csdnimg.cn/img_convert/c5e8200d182e63bf803bd0d057366f4c.png)