PDO
PHP 数据对象(PDO)扩展为 PHP 访问数据库定义了一个轻量级的一致接口。实现 PDO 接口的每个数据库驱动可以将特定具体数据库的特性公开作为标准扩展函数。注意不能单独使用 PDO 扩展执行任何数据库功能;必须使用具体数据库的 PDO 驱动程序来访问数据库服务器。
PDO 提供了数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数来查询和获取数据。PDO 不提供数据库抽象;不会重写 SQL 或模拟缺失的特性。如果需要,应该使用成熟的抽象层。
数据库支持:firebird,informix,mysql,mssql,odbc,pgsql,sqlite。
PDO 类 和 PDOStatement 类
1. PDO 类
class PDO {
/* 方法 */
public __construct(
string $dsn,
?string $username = null,
?string $password = null,
?array $options = null
)
public beginTransaction(): bool
public commit(): bool
public errorCode(): ?string
public errorInfo(): array
public exec(string $statement): int|false
public getAttribute(int $attribute): mixed
public static getAvailableDrivers(): array
public inTransaction(): bool
public lastInsertId(?string $name = null): string|false
public prepare(string $query, array $options = []): PDOStatement|false
public query(string $query, ?int $fetchMode = null): PDOStatement|false
public query(string $query, ?int $fetchMode = PDO::FETCH_COLUMN, int $colno): PDOStatement|false
public query(
string $query,
?int $fetchMode = PDO::FETCH_CLASS,
string $classname,
array $constructorArgs
): PDOStatement|false
public query(string $query, ?int $fetchMode = PDO::FETCH_INTO, object $object): PDOStatement|false
public quote(string $string, int $type = PDO::PARAM_STR): string|false
public rollBack(): bool
public setAttribute(int $attribute, mixed $value): bool
}
- PDO::beginTransaction — 启动一个事务
- PDO::commit — 提交一个事务
- PDO::__construct — 创建一个表示数据库连接的 PDO 实例
- PDO::errorCode — 获取跟数据库句柄上一次操作相关的 SQLSTATE
- PDO::errorInfo — Fetch extended error information associated with the last operation on the database handle
- PDO::exec — 执行 SQL 语句,并返回受影响的行数
- PDO::getAttribute — 取回一个数据库连接的属性
- PDO::getAvailableDrivers — 返回一个可用驱动的数组
- PDO::inTransaction — 检查是否在事务内
- PDO::lastInsertId — 返回最后插入行的ID或序列值
- PDO::prepare — 预处理要执行的语句,并返回语句对象
- PDO::query — 预处理并执行没有占位符的 SQL 语句
- PDO::quote — 为 SQL 查询里的字符串添加引号
- PDO::rollBack — 回滚事务
- PDO::setAttribute — 设置属性
2. PDOStatement 类
class PDOStatement implements IteratorAggregate {
/* 属性 */
public string $queryString;
/* 方法 */
public bindColumn(
string|int $column,
mixed &$var,
int $type = PDO::PARAM_STR,
int $maxLength = 0,
mixed $driverOptions = null
): bool
public bindParam(
string|int $param,
mixed &$var,
int $type = PDO::PARAM_STR,
int $maxLength = 0,
mixed $driverOptions = null
): bool
public bindValue(string|int $param, mixed $value, int $type = PDO::PARAM_STR): bool
public closeCursor(): bool
public columnCount(): int
public debugDumpParams(): ?bool
public errorCode(): ?string
public errorInfo(): array
public execute(?array $params = null): bool
public fetch(int $mode = PDO::FETCH_DEFAULT, int $cursorOrientation = PDO::FETCH_ORI_NEXT, int $cursorOffset = 0): mixed
public fetchAll(int $mode = PDO::FETCH_DEFAULT): array
public fetchAll(int $mode = PDO::FETCH_COLUMN, int $column): array
public fetchAll(int $mode = PDO::FETCH_CLASS, string $class, ?array $constructorArgs): array
public fetchAll(int $mode = PDO::FETCH_FUNC, callable $callback): array
public fetchColumn(int $column = 0): mixed
public fetchObject(?string $class = "stdClass", array $constructorArgs = []): object|false
public getAttribute(int $name): mixed
public getColumnMeta(int $column): array|false
public getIterator(): Iterator
public nextRowset(): bool
public rowCount(): int
public setAttribute(int $attribute, mixed $value): bool
public setFetchMode(int $mode): bool
public setFetchMode(int $mode = PDO::FETCH_COLUMN, int $colno): bool
public setFetchMode(int $mode = PDO::FETCH_CLASS, string $class, ?array $constructorArgs = null): bool
public setFetchMode(int $mode = PDO::FETCH_INTO, object $object): bool
}
- PDOStatement::bindColumn— 绑定一列到一个 PHP 变量
- PDOStatement::bindParam— 绑定一个参数到指定的变量名
- PDOStatement::bindValue — 把一个值绑定到一个参数
- PDOStatement::closeCursor — 关闭游标,使语句能再次被执行
- PDOStatement::columnCount — 返回结果集中的列数
- PDOStatement::debugDumpParams — 打印一条 SQL 预处理命令
- PDOStatement::errorCode — 获取跟上一次语句句柄操作相关的 SQLSTATE
- PDOStatement::errorInfo — 获取跟上一次语句句柄操作相关的扩展错误信息
- PDOStatement::execute — 执行预处理语句
- PDOStatement::fetch — 从结果集中获取下一行
- PDOStatement::fetchAll — 从结果集中获取剩余的行
- PDOStatement::fetchColumn — 从结果集中的下一行返回单独的一列
- PDOStatement::fetchObject — 获取下一行并作为一个对象返回
- PDOStatement::getAttribute — 检索语句属性
- PDOStatement::getColumnMeta — 返回结果集中一列的元数据
- PDOStatement::getIterator — Gets result set iterator
- PDOStatement::nextRowset — 在一个多行集合语句句柄中推进到下一个行集合
- PDOStatement::rowCount — 返回受上一个 SQL 语句影响的行数
- PDOStatement::setAttribute — 设置一个语句属性
- PDOStatement::setFetchMode — 为语句设置默认的获取模式
PDO的使用
1.pdo的简单使用
使用pdo操纵数据库,大致分为以下几步:
- 连接数据库,获取PDO实例对象, 使用
new PDO($dsn,$username,$password,[])
获取PDO实例对象,$dsn
为数据库的类型mysql,oracle…以及要操纵的数据库名称,以及访问的主机名,$username,$password
为对应的数据库的账户和密码;[]
为一些不必要参数,如指定数据库编码方式,一些预定义常量… - 编写sql语句,crud 增删改查
- 使用
$pdo->query($sql)
执行sql,并且以PDOStatement对象返回结果集,如果没找到结果集则返回false。 - 可以使用
fetch()
(从结果集中获取下一行),fetchAll()
(从结果集中获取剩余的行),fetchColumn()
( 从结果集中的下一行返回单独的一列),fetchObject()
(获取下一行并作为一个对象返回)…的方式来遍历结果集。
比如下面的例子,查询某个表的所有数据,并且遍历打印数据:
<?php
$type = 'mysql'; // 数据库为mysql数据库
$hostname = 'localhost'; // 主机名为本地服务器
$username ='root'; // mysql 的账户
$password = 'root'; // mysql 的密码
$dbname = 'phpdemo'; // 操纵的数据库名
try{
$dsn = "$type:dbname=$dbname;host=$hostname";
// 初始化 pdo对象
$pdo = new PDO($dsn,$username,$password,[
// 开启异常模式
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
}catch (PDOException $e){
die("数据库连接失败:".$e->getMessage());
}
// 使用pdo->query() 预处理并执行sql语句,以 PDOStatement 对象形式返回结果集,
// 如果数据不存在则返回false
$stmt = $pdo->query('select * from book');
// 以关联数组的方式将结果集返回
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 打印输出sql查询到的数据
echo "<pre>";
var_dump($data);
echo "</pre>";
2.预定义占位符
PDO对预处理语句的支持需要使用PDOStatement类对象,但该类对象并不是通过NEW关键字实例化出来的,而是通过PDO对象中的prepare()方法,在数据库服务器中准备好一个预处理的SQL语句后直接返回的。
如果通过之前执行PDO对象中的query()方法返回的PDOStatement类对象,只代表的是一个结果集对象。
而如果通过执行PDO对象中的prepare()方法产生的PDOStatement类对象,则为一个查询对象,能定义和执行参数化的SQL命令。
使用PDOStatement类对象对sql进行预处理的步骤大致分为如下几步:
- 连接数据库,获取PDO实例对象
$pdo = new PDO($dsn,$username,$password);
- 准备要预处理的sql语句 ,
$sql = "select * from book where id = ?" 或者 $sql = "select * from book where id=:id"
(预定义占位符的sql语句) - 使用PDO实例对象的prepare()方法,得到PDOStatement类对象 ,
$stmt = $pdo->prepare($sql,)
- 使用PDOStatement类对象的bindParam()方法,绑定对应的预定义占位符
- 使用PDOStatement类对象的execute()方法,正式执行sql.
<?php
$type = 'mysql'; // 数据库为mysql数据库
$hostname = 'localhost'; // 主机名为本地服务器
$username ='root'; // mysql 的账户
$password = 'root'; // mysql 的密码
$dbname = 'phpdemo'; // 操纵的数据库名
try{
$dsn = "$type:dbname=$dbname;host=$hostname";
// 初始化 pdo对象
$pdo = new PDO($dsn,$username,$password,[
// 开启异常模式
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
}catch (PDOException $e){
die("数据库连接失败:".$e->getMessage());
}
$sql = "insert into book (booKName,bookPrice,author) values(?,?,?)";
// 预处理sql获取pdostatement对象
$stmt = $pdo->prepare($sql);
// 绑定预定义占位符
$bookName = "大话数据结构";
$bookPrice = "40";
$author = "大牛";
$stmt->bindParam(1,$bookName);
$stmt->bindParam(2,$bookPrice);
$stmt->bindParam(3,$author);
// 执行sql
$stmt->execute();
上面预定义占位符绑定的方式,还有bindColumn()
绑定一列到一个 PHP 变量即字段列和变量对应 和 bindValue()
把一个值绑定到一个参数。
那么上面的代码可以修改如下(使用bindValue的方式):
// ....
$sql = "insert into book (booKName,bookPrice,author) values(:bookName,:bookPrice,:author)";
// 预处理sql获取pdostatement对象
$stmt = $pdo->prepare($sql);
// 绑定预定义占位符
$bookName = "大话数据结构";
$bookPrice = "40";
$author = "大牛";
$stmt->bindValue(":bookName",$bookName,PDO::PARAM_STR);
$stmt->bindValue(":bookPrice",$bookPrice,PDO::PARAM_STR);
$stmt->bindValue(":author",$author,PDO::PARAM_STR);
// 执行sql
$stmt->execute();
小结
使用PDO可以对不同的数据库进行操纵,pdo提供了轻量级的访问数据库的统一接口,对数据访问提供了抽象层,无论使用何种数据库,都可以使用相同的代码去操纵。
1.使用PDO操纵数据库的步骤:
- 连接对应的数据库,生成PDO实例对象 ,
$pdo = new PDO($dsn,$uname,$upwd)
- 准备sql语句
- 使用PDO->query()方法,执行对应的sql,并且返回一个PDOStatement对象 ,
$stmt = $pdo->query($sql)
- 可以使用PDOStatement对象来获取数据,它提供了一系列的fetch()方法…,
$data = $stmt->fetch()
2.使用PDO操纵数据库,且SQL存在预定义占位符的大致步骤:
- 连接数据库
$pdo = new PDO($dsn,$uname,$upwd)
- 准备含占位符的sql语句
- 预处理sql,
$stmt=$pdo->prepare($sql)
- 绑定参数 ,
$stmt->bindParam()
- 执行Sql,
$stmt->excute()
3.使用bindValue和bindParam绑定预定义占位符参数的区别:
方法 bindParam() 和 bindValue() 非常相似,唯一的区别就是前者使用一个PHP变量绑定参数,而后者使用一个值。
所以使用bindParam是第二个参数只能用变量名,而不能用变量值,而bindValue至可以使用具体值。
4.预定义占位符的不同形式:
隐式占位符 ?
,例如 $sql = "insert into book (booKName,bookPrice,author) values(?,?,?)";
显示占位符 :占位符名称
, 例如 $sql = "insert into book (booKName,bookPrice,author) values(:bookName,:bookPrice,:author)";