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

简介: 本文介绍了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)";


相关文章
|
10天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
6天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2506 14
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
6天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1519 14
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
8天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
531 13
|
1月前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19282 30
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18836 20
|
1月前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17524 13
Apache Paimon V0.9最新进展
|
8天前
|
人工智能 自动驾驶 机器人
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
过去22个月,AI发展速度超过任何历史时期,但我们依然还处于AGI变革的早期。生成式AI最大的想象力,绝不是在手机屏幕上做一两个新的超级app,而是接管数字世界,改变物理世界。
458 48
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
|
1天前
|
云安全 存储 运维
叮咚!您有一份六大必做安全操作清单,请查收
云安全态势管理(CSPM)开启免费试用
355 4
叮咚!您有一份六大必做安全操作清单,请查收
|
2天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。