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

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 本文介绍了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)";


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
5月前
|
存储 SQL 运维
速看!数据库与数据仓库的本质区别是什么?
本文深入解析了“数据库”与“数据仓库”的核心区别,涵盖设计目的、数据结构、使用场景、性能优化和数据更新五个维度。数据库主要用于支持实时业务操作,强调事务处理效率;数据仓库则面向企业分析决策,注重海量数据的整合与查询性能。二者在企业中各司其职,缺一不可。
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库中的 char 与 varchar的区别是什么
MySQL中的char和varchar均用于存储字符串,但有显著区别。char为定长类型,固定长度,存储空间始终为设定值,适合长度固定的数据如手机号。varchar为变长类型,仅占用实际数据所需空间,适合长度不固定的内容如用户名。二者在性能与空间利用上各有优劣,应根据实际场景合理选择。
483 0
|
12月前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
448 25
|
11月前
|
SQL NoSQL Oracle
关系型与非关系型数据库的区别
关系型数据库是依据关系模型来创建的数据库,所谓关系模型就是“一对一”、“一对多”、“对多对”等。常见的关系型数据库有Oracle、MySQL、SQL Server等。非关系型数据库主要基于“非关系型模型”,其中非关系型模型有:列模型、键值对模型、文档类模型。比如redis属于键值对模型。 MongoDB属于文档模型 关系型数据库的优点: ● 易于维护:都是使用表结构,格式一致。 ● 使用方便:SQL语言通用,可用于复杂查询。 ● 复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。 关系型数据库的缺点: ● 读写性能比较差,尤其是海量数据的高效率读写。 ● 固定的表结构,灵活
|
11月前
|
数据库连接 PHP 数据库
【YashanDB知识库】PHP使用ODBC使用数据库绑定参数功能异常
【YashanDB知识库】PHP使用ODBC使用数据库绑定参数功能异常
|
11月前
|
PHP 数据库
【YashanDB知识库】PHP使用OCI接口使用数据库绑定参数功能异常
【YashanDB知识库】PHP使用OCI接口使用数据库绑定参数功能异常
|
11月前
|
SQL 存储 关系型数据库
在PG数据库中,not in 和except的区别
在PG数据库中,not in 和except的区别
|
5月前
|
关系型数据库 MySQL PHP
PHP和Mysql前后端交互效果实现
本文介绍了使用PHP连接MySQL数据库的基本函数及其实现案例。内容涵盖数据库连接、选择数据库、执行查询、获取结果等常用操作,并通过用户登录和修改密码的功能实例,展示了PHP与MySQL的交互过程及代码实现。
392 0
PHP和Mysql前后端交互效果实现
|
10月前
|
关系型数据库 MySQL Linux
查看Linux、Apache、MySQL、PHP版本的技巧
以上就是查看Linux、Apache、MySQL、PHP版本信息的方法。希望这些信息能帮助你更好地理解和使用你的LAMP技术栈。
499 17