PHP-PDO对象

PHP 2020-02-18 224 次浏览 次点赞

PDO概述

数据库有很多种,MySQL、sqserver、Oracle、db2......通过PHP去连接数据库的时候使用的扩展是不一样的,这就导致更换数据库时比较麻烦,因为不同扩展库的API不同,代码逻辑、函数需要更改......那么有没有一套扩展库可以直接用来连接所有的数据库呢?有,就是PDO(php data object)

百度释义:PDO(PHP Data Objects)是一种在PHP里连接数据库的使用接口。PDO与mysqli曾经被建议用来取代原本PHP在用的mysql相关函数,基于数据库使用的安全性,因为后者欠缺对于SQL注入的防护。

图示:

pdo.png

在info中查看已安装的

info.png

wamp PHP扩展启用:

PDO的使用

主要是这三个类 PDO、PDOStatement、PDOException

dsn(data source name)

数据源名称或叫做 DSN,包含了请求连接到数据库的信息。通常,一个 DSN 由 PDO 驱动名、紧随其后的冒号、以及具体 PDO 驱动的连接语法组成。

创建PDO对象

PDO::__construct ( string $dsn [, string $username [, string $password [, array $driver_options ]]] )

创建一个表示连接到请求数据库的数据库连接 PDO 实例。

<?php

$dsn = 'mysql:dbname=pdo_demo;host:localhost;charset=utf8';
//这里我将host放在了紧挨着mysql后边,数据库连接没问题,但是在之后的执行sql语句中报了错:
//SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected
//将dbname前移就好了,手册里有讲,难道版本升级后顺序变了?

try {
    $pdo = new PDO($dsn, 'root', '');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die('数据库连接失败:'.$e->getMessage());
}

1、字符串形式:'mysql:host:localhost;dbname=pdo_demo;charset=utf8';

2、文件形式:uri:file:///path/to/dsnfile

3、php.ini

获取和设置信息

​ PDO::getAttribute — 取回一个数据库连接的属性

​ PDO::setAttribute — 设置属性

PDO执行sql语句

  • exec 执行不要结果集的语句 比如:增删改
  • query 执行要结果集的语句 比如:插 desc
  • lastInsertId 最后插入语句的id号

PDO错误模式

1、默认

2、警告:

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

3、异常:

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
<?php

$dsn = 'mysql:dbname=pdo_demo;host:localhost;charset=utf8';
try {
    $pdo = new PDO($dsn, 'root', '');
    //在创建完PDO对象的时候设置错误模式
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die('数据库连接失败:'.$e->getMessage());
}
try {
    $sql = 'insert into user(name, pwd) values("fmujie", "123456")';

    $ret = $pdo->exec($sql);
    if ($ret > 0) {
        echo '插入成功';
        //返回插入的id索引
        echo $pdo->lastInsertId();
    } else {
        echo '插入失败';
    } 
} catch (PDOException $e) {
    echo $e->getMessage();
}
查询

PDO::query() returns a PDOStatement object, or FALSE on failure.

try {
    $sql = 'select * from user';

    $ret = $pdo->query($sql);
    var_dump($ret);
} catch (PDOException $e) {
    echo $e->getMessage();
}

query.png

PDO的事务处理

​ 比如:转账 A转出和B转入要都正确无误,否则交易失败(把多条sql语句作为一个整体(事务)来执行,如果其中有一条sql语句执行失败,所有的sql语句都要执行失败,将状态回滚到初始状态)

​ 表的引擎有两种 myisam (不支持) innodb(支持)
database.png

$pdo->beginTransaction();    开启一个事务//在执行sql语句之前
$pdo->commit();                提交事务
$pdo->rollback();           回滚到初始状态
try {
    $pdo->beginTransaction();
    $sql = '';
    $ret = $pdo->exec($sql);
    if ($ret > 0) {
        echo '执行成功';
        //返回插入的id索引
        echo $pdo->lastInsertId();
    } else {
        throw new PDOException('执行失败');
    }
    $sql = '';
    $ret = $pdo->exec($sql);
    if ($ret > 0) {
        echo '执行成功';
        //返回插入的id索引
        echo $pdo->lastInsertId();
    } else { 
        throw new PDOException('执行失败');
    }
    
    $pdo->commit();
    echo '执行都成功';
} catch (PDOException $e) {
    $pdo->rollback();
    echo $e->getMessage();
}

预处理语句

优点
  • 效率
  • 安全(sql注入)

平差我们每插入一条语句便写一条insert的sql语句,php每次都得编译生成,这样重复的向同一个表中插入语句会造成很大的资源浪费。使用预处理语句对于相同的sql语句,在值的部分使用占位符,这样在程序编译的时候只需要编译一条sql语句,Then以下添不同的值就ok了,这样的效率无疑会提升许多。

PDOStatement::bindParam — 绑定一个参数到指定的变量名

  • parameter

    参数标识符。对于使用命名占位符的预处理语句,应是类似 :name 形式的参数名。对于使用问号占位符的预处理语句,应是以1开始索引的参数位置。

增删改

增加:

$stmt = $pdo->prepare('insert into user(name, pwd) values(?, ?)')

$stmt->bindParam(1, $name);
$stmt->bindParam(2, $pwd);
$name = '...';
$pwd = '...';
$stmt->execute();
//或者
$stmt = $pdo->prepare('insert into user(name, pwd) values(:name, :pwd)');
$stmt->bindParam(':name', $name);
$stmt->bindParam(':pwd', $pwd);
$name = '...';
$pwd = '...';
$stmt->execute();
//写起来比较麻烦,重复太多
$stmt->execute(['...', '...']);   //?占位符使用索引数组
$stmt->execute([':name'=> '...', ':pwd'=> '...']);   //:占位符使用关联数组

PDO提取结果集

select query()返回的 $ret

try {
   $stmt = $pdo->prepare('select * from user');
   $stmt->execute();
   $res = $stmt->fetch();//默认是索引数组和关联数组都有  一条
   $result = $stmt->fetchAll();//取出全部
    var_dump($res);
} catch (PDOException $e) {
    echo $e->getMessage();
}

控制下一行如何返回给调用者。此值必须是 PDO::FETCH_* 系列常量中的一个,缺省为 PDO::ATTR_DEFAULT_FETCH_MODE 的值 (默认为 PDO::FETCH_BOTH )。

• PDO::FETCH_ASSOC:返回一个索引为结果集列名的数组

• PDO::FETCH_BOTH(默认):返回一个索引为结果集列名和以0开始的列号的数组

• PDO::FETCH_NUM:返回一个索引为以0开始的结果集列号的数组

• PDO::FETCH_OBJ:返回一个属性名对应结果集列名的匿名对象

(常用)


本文由 fmujie 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论

召唤看板娘