php连接数据库之PDO,PDO的简单使用和预定义占位符的使用以及PDOStatement对象的使用,占位符的不同形式,bindValue和bindParam绑定预定义占位符参数的区别

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 本文介绍了PHP中PDO(PHP Data Objects)扩展的基本概念和使用方法。内容包括PDO类和PDOStatement类的介绍,PDO的简单使用,预定义占位符的使用方法,以及PDOStatement对象的使用。文章还讨论了绑定预定义占位符参数的不同形式,即bindValue和bindParam的区别。通过具体示例,展示了如何使用PDO进行数据库连接、数据查询、数据插入等操作。

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
}
  1. PDO::beginTransaction — 启动一个事务
  2. PDO::commit — 提交一个事务
  3. PDO::__construct — 创建一个表示数据库连接的 PDO 实例
  4. PDO::errorCode — 获取跟数据库句柄上一次操作相关的 SQLSTATE
  5. PDO::errorInfo — Fetch extended error information associated with the last operation on the database handle
  6. PDO::exec — 执行 SQL 语句,并返回受影响的行数
  7. PDO::getAttribute — 取回一个数据库连接的属性
  8. PDO::getAvailableDrivers — 返回一个可用驱动的数组
  9. PDO::inTransaction — 检查是否在事务内
  10. PDO::lastInsertId — 返回最后插入行的ID或序列值
  11. PDO::prepare — 预处理要执行的语句,并返回语句对象
  12. PDO::query — 预处理并执行没有占位符的 SQL 语句
  13. PDO::quote — 为 SQL 查询里的字符串添加引号
  14. PDO::rollBack — 回滚事务
  15. 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
}
  1. PDOStatement::bindColumn— 绑定一列到一个 PHP 变量
  2. PDOStatement::bindParam— 绑定一个参数到指定的变量名
  3. PDOStatement::bindValue — 把一个值绑定到一个参数
  4. PDOStatement::closeCursor — 关闭游标,使语句能再次被执行
  5. PDOStatement::columnCount — 返回结果集中的列数
  6. PDOStatement::debugDumpParams — 打印一条 SQL 预处理命令
  7. PDOStatement::errorCode — 获取跟上一次语句句柄操作相关的 SQLSTATE
  8. PDOStatement::errorInfo — 获取跟上一次语句句柄操作相关的扩展错误信息
  9. PDOStatement::execute — 执行预处理语句
  10. PDOStatement::fetch — 从结果集中获取下一行
  11. PDOStatement::fetchAll — 从结果集中获取剩余的行
  12. PDOStatement::fetchColumn — 从结果集中的下一行返回单独的一列
  13. PDOStatement::fetchObject — 获取下一行并作为一个对象返回
  14. PDOStatement::getAttribute — 检索语句属性
  15. PDOStatement::getColumnMeta — 返回结果集中一列的元数据
  16. PDOStatement::getIterator — Gets result set iterator
  17. PDOStatement::nextRowset — 在一个多行集合语句句柄中推进到下一个行集合
  18. PDOStatement::rowCount — 返回受上一个 SQL 语句影响的行数
  19. PDOStatement::setAttribute — 设置一个语句属性
  20. PDOStatement::setFetchMode — 为语句设置默认的获取模式

PDO的使用

1.pdo的简单使用

使用pdo操纵数据库,大致分为以下几步:

  1. 连接数据库,获取PDO实例对象, 使用 new PDO($dsn,$username,$password,[])获取PDO实例对象,$dsn为数据库的类型mysql,oracle…以及要操纵的数据库名称,以及访问的主机名,$username,$password为对应的数据库的账户和密码;[]为一些不必要参数,如指定数据库编码方式,一些预定义常量…
  2. 编写sql语句,crud 增删改查
  3. 使用$pdo->query($sql)执行sql,并且以PDOStatement对象返回结果集,如果没找到结果集则返回false。
  4. 可以使用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进行预处理的步骤大致分为如下几步:

  1. 连接数据库,获取PDO实例对象 $pdo = new PDO($dsn,$username,$password);
  2. 准备要预处理的sql语句 ,$sql = "select * from book where id = ?" 或者 $sql = "select * from book where id=:id" (预定义占位符的sql语句)
  3. 使用PDO实例对象的prepare()方法,得到PDOStatement类对象 ,$stmt = $pdo->prepare($sql,)
  4. 使用PDOStatement类对象的bindParam()方法,绑定对应的预定义占位符
  5. 使用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操纵数据库的步骤:

  1. 连接对应的数据库,生成PDO实例对象 ,$pdo = new PDO($dsn,$uname,$upwd)
  2. 准备sql语句
  3. 使用PDO->query()方法,执行对应的sql,并且返回一个PDOStatement对象 ,$stmt = $pdo->query($sql)
  4. 可以使用PDOStatement对象来获取数据,它提供了一系列的fetch()方法…,$data = $stmt->fetch()

2.使用PDO操纵数据库,且SQL存在预定义占位符的大致步骤:

  1. 连接数据库 $pdo = new PDO($dsn,$uname,$upwd)
  2. 准备含占位符的sql语句
  3. 预处理sql, $stmt=$pdo->prepare($sql)
  4. 绑定参数 ,$stmt->bindParam()
  5. 执行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)";


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
8天前
|
SQL Java 数据库连接
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率。本文介绍了连接池的工作原理、优势及实现方法,并提供了HikariCP的示例代码。
20 3
|
8天前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
11 1
|
8天前
|
Java 数据库连接 数据库
Java连接池在数据库性能优化中的重要作用。连接池通过预先创建和管理数据库连接,避免了频繁创建和关闭连接的开销
本文深入探讨了Java连接池在数据库性能优化中的重要作用。连接池通过预先创建和管理数据库连接,避免了频繁创建和关闭连接的开销,显著提升了系统的响应速度和吞吐量。文章介绍了连接池的工作原理,并以HikariCP为例,展示了如何在Java应用中使用连接池。通过合理配置和优化,连接池技术能够有效提升应用性能。
23 1
|
2天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
6 0
|
10天前
|
SQL 关系型数据库 数据库连接
"Nacos 2.1.0版本数据库配置写入难题破解攻略:一步步教你排查连接、权限和配置问题,重启服务轻松解决!"
【10月更文挑战第23天】在使用Nacos 2.1.0版本时,可能会遇到无法将配置信息写入数据库的问题。本文将引导你逐步解决这一问题,包括检查数据库连接、用户权限、Nacos配置文件,并提供示例代码和详细步骤。通过这些方法,你可以有效解决配置写入失败的问题。
30 0
|
23天前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
56 3
Mysql(4)—数据库索引
|
9天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
45 2
|
12天前
|
存储 关系型数据库 MySQL
MySQL vs. PostgreSQL:选择适合你的开源数据库
在众多开源数据库中,MySQL和PostgreSQL无疑是最受欢迎的两个。它们都有着强大的功能、广泛的社区支持和丰富的生态系统。然而,它们在设计理念、性能特点、功能特性等方面存在着显著的差异。本文将从这三个方面对MySQL和PostgreSQL进行比较,以帮助您选择更适合您需求的开源数据库。
53 4
|
17天前
|
存储 关系型数据库 MySQL
如何在MySQL中创建数据库?
【10月更文挑战第16天】如何在MySQL中创建数据库?
|
21天前
|
SQL Oracle 关系型数据库
安装最新 MySQL 8.0 数据库(教学用)
安装最新 MySQL 8.0 数据库(教学用)
93 4