0

0

PHP之详解PDO

*文

*文

发布时间:2017-12-26 17:07:33

|

22018人浏览过

|

来源于php中文网

原创

本文主要介绍了详解php中的pdo类,pdo类可以帮助人们更加方便地在php中使用数据库。希望对大家使用pdo有所帮助。

 简介

咱一起来看看PDO类。PDO是PHP Data Objects的缩写,它被描述为“在PHP中访问数据库的轻量级,兼容性的接口”。尽管它的名字不咋好听,但PDO是一个在PHP中访问数据库会让人喜爱的方式。
与MySQLi的不同

MySQLi和PDO很相似,都有两方面主要区别:

1.MySQLi只能访问MySQL,但PDO可以访问12种不同的数据库

立即学习PHP免费学习笔记(深入)”;

2.PDO没有普通函数调用(mysqli_*functions)
开始步骤

首先,你得确定一下你的PHP是否安装了PDO插件。你可以用$test=new PDO()的结果来测试。如果提示说是参数不匹配,那证明已经安装了PDO插件,如果说是对象不存在,你得先确认一下在pho.ini中php_pdo_yourssqlserverhere.extis是否被注释掉了。如果没有这句话,那你得安装PDO了,这里就不啰嗦了。

连接

现在我们确认服务器已经工作,开始连接数据库吧:
 

$dsn = 'mysql:dbname=demo;host=localhost;port=3306';
$username = 'root';
$password = 'password_here';
try {
 $db = new PDO($dsn, $username, $password); // also allows an extra parameter of configuration
} catch(PDOException $e) {
 die('Could not connect to the database:
' . $e); }

除$dsn之外,所有语句和变量都能自我解释。DSN指的是数据源名称,有多种输入类型。最常见的一种是我们刚刚用的这种,PHP官网解释了 其他可用的DSN 。

你可以省去DSN的其他额外参数,只需要在数据库驱动后面带个冒号,比如(mysql:)。在这种情况下PDO将会尝试连接到本地数据库。就像当你使用MySQLi时需要在查询中指定数据库名称一样。

最后一件你需要注意的事情就是我们用try-catch块包裹了我们的初始化对象。PDO连接失败的时候将会抛出PDOException异常而不是查询失败的时候。如果你愿意你可以使用下面代码$db=line来选择异常的模式。
 

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

或者你可以直接在PDO初始化时传递参数:
 

$db = new PDO($dsn, $username, $password, array (
 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));

我们现在使用的是错误的方式——在失败时候简单返回false,我们是没有理由不对异常进行处理的。

基本查询

在PDO中使用query和exec两种方法使得对数据库查询变得非常简单。如果你想得到查询结果的行数exec是非常好用的,因此对SELECT查询语句是非常有用的。

现在我们通过下面的一个例子查看这两种方法:
 

$statement = <<query($statement);

假设我们的查询是正确的,$foods现在是一个PDO Statement对象,我们可以用它获取到我们的结果或者是查看这次查询中一共查到多少条结果集。
行数

不足的是,PDO没有提供一个统一的方法去计算返回的行数。PDO Statement包含了一个叫做rowCount的方法,但是这个方法却不能保证在每一个SQL驱动中起作用(幸运的是,它能够在Mysql数据库中起作用)。

如果你的SQL驱动不支持这个方法,你也有2个选择:使用二次查询(SELECT COUNT(*))或者使用简单的count($foods)得到行数。

幸运的是对我们的MySQL例子,我们可以使用下面的简单方法来输出正确的行数。
 

echo $foods->rowCount();

遍历结果集

打印出这些可口的食物一点也不困难:
 

foreach($foods->FetchAll() as $food) {
 echo $food['name'] . '
'; }

唯一需要注意的是PDO也支持Fetch方法,这个方法只会返回第一条结果,这对于只需要查询一条结果集是非常有用的。
转义用户输入(的特殊字符)

你可曾听说过(mysqli_)real_escape_string,这是用于确保用户输入安全数据。PDO提供了一个方法叫做quote,这个方法可以把输入字符串中带有引号的地方进行特殊字符转义。
 

$input: this is's' a '''pretty dange'rous str'ing

在转义后,最终得到下面结果:
 

$db->quote($input): 'this is\'s\' a \'\'\'pretty dange\'rous str\'ing'
exec()

正如上面提到的,你可以使用exec()方法实现UPDATE,DELETE和INSERT 操作,执行后它会返回受影响行数的数量:
 

$statement = <<exec($statement); // outputs number of deleted rows

预处理语句

尽管exec方法和查询在PHP中仍然被大量使用和支持,但是PHP官网上还是要求大家用预处理语句的方式来替代。为什么呢?主要是因为:它更安全。预处理语句不会直接在实际查询中插入参数,这就避免了许多潜在的SQL注入。

然而出于某种原因,PDO实际上并没有真正的使用预处理,它是在模拟预处理方式,在将语句传给SQL服务器之前会把参数数据插入到语句中,这使得某些系统容易受到SQL注入。

ERMEB域名PHP离线网络授权系统
ERMEB域名PHP离线网络授权系统

感谢您选择使用ERMEB域名授权离线网络验证系统(简称:ERMEB域名授权系统)是ERMEB团队开发,ERMEB域名授权系统是国内最稳定,最强大,最先进的域名授权管理平台解决方案之一,ERMEB域名授权系统采用PHP +Mysql的技术,ERMEB域名授权系统框架使用Thinkphp6/mysql数据库基于Markdown开发者文档开发而成,项目安装请参考ThinkPHP官方文档及下面的服务环境说

下载

如果你的SQL服务器不真正的支持预处理,我们可以很容易的通过如下方式在PDO初始化时传参来修复这个问题:
 

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

接下来开始我们的第一个预处理语句吧:
 

$statement = $db->prepare('SELECT * FROM foods WHERE `name`=? AND `healthy`=?');
$statement2 = $db->prepare('SELECT * FROM foods WHERE `name`=:name AND `healthy`=:healthy)';

正如你所见,有两种创建参数的方法,命名的与匿名的(不可以同时出现在一个语句中)。然后你可以使用bindValue来敲进你的输入:
 

$statement->bindValue(1, 'Cake');
$statement->bindValue(2, true);
 
$statement2->bindValue(':name', 'Pie');
$statement2->bindValue(':healthy', false);

注意使用命名参数的时候你要包含进冒号(:)。PDO还有一个bindParam方法,可以通过引用绑定数值,也就是说它只在语句执行的时候查找相应数值。

现在剩下的唯一要做的事情,就是执行我们的语句:
 

$statement->execute();
$statement2->execute();
 
// Get our results:
$cake = $statement->Fetch();
$pie = $statement2->Fetch();

为了避免只使用bindValue带来的代码碎片,你可以用数组给execute方法作为参数,像这样:
 

$statement->execute(array(1 => 'Cake', 2 => true));
$statement2->execute(array(':name' => 'Pie', ':healthy' => false));

事务

前面我们已经描述过了什么是事务:

一个事务就是执行一组查询,但是并不保存他们的影响到数据库中。这样做的好处是如果你执行了4条相互依赖的插入语句,当有一条失败后,你可以回滚使得其他的数据不能够插入到数据库中,确保相互依赖的字段能够正确的插入。你需要确保你使用的数据库引擎支持事务。
开启事务

你可以很简单的使用beginTransaction()方法开启一个事务:
 

$db->beginTransaction();
 
$db->inTransaction(); // true!

然后你可以继续执行你的数据库操作语句,在最后提交事务:
 

$db->commit();

还有类似MySQLi中的rollBack()方法,但是它并不是回滚所有的类型(例如在MySQL中使用DROP TABLE),这个方法并不是真正的可靠,我建议尽量避免依赖此方法。

其他有用的选项

有几个选项你可以考虑用一下。这些可以作为你的对象初始化时候的第四个参数输入。

 $options = array($option1 => $value1, $option[..]);
$db = new PDO($dsn, $username, $password, $options);

PDO::ATTR_DEFAULT_FETCH_MODE

你可以选择PDO将返回的是什么类型的结果集,如PDO::FETCH_ASSOC,会允许你使用$result['column_name'],或者PDO::FETCH_OBJ,会返回一个匿名对象,以便你使用$result->column_name

你还可以将结果放入一个特定的类(模型),可以通过给每一个单独的查询设置一个读取模式,就像这样:
 

$query = $db->query('SELECT * FROM `foods`');
$foods = $query->fetchAll(PDO::FETCH_CLASS, 'Food');

- 所有读取模式

上面我们已经解释过这一条了,但喜欢TryCatch的人需要用到:PDO::ERRMODE_EXCEPTION。如果不论什么原因你想抛出PHP警告,就使用PDO::ERRMODE_WARNING。

PDO::ATTR_TIMEOUT

当你为载入时间而着急时,你可以使用此属性来为你的查询指定一个超时时间,单位是秒. 注意,如果超过你设置的时间,缺省会抛出E_WARNING异常, 除非 PDO::ATTR_ERRMODE 被改变.

更多属性信息可以在 PHP官网的属性设置 里查看到.
最后的思考

PDO是一个在PHP中访问你的数据库的很棒的方式,可以认为是最好的方式。除非你拒绝使用面向对象的方法或是太习惯 MySQLi 的方法名称,否则没有理由不使用PDO。

更好的是完全切换到只使用预处理语句,这最终将使你的生活更轻松!

相关推荐:

php如何利用PDO访问oracle数据库的方法详解

PHP中关于PDO数据访问抽象层的功能操作的介绍

使用PDO操作MySQL数据库的实例分享(收藏)

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

公务员递补名单公布时间 公务员递补要求
公务员递补名单公布时间 公务员递补要求

公务员递补名单公布时间不固定,通常在面试前,由招录单位(如国家知识产权局、海关等)发布,依据是原入围考生放弃资格,会按笔试成绩从高到低递补,递补考生需按公告要求限时确认并提交材料,及时参加面试/体检等后续环节。要求核心是按招录单位公告及时响应、提交材料(确认书、资格复审材料)并准时参加面试。

44

2026.01.15

公务员调剂条件 2026调剂公告时间
公务员调剂条件 2026调剂公告时间

(一)符合拟调剂职位所要求的资格条件。 (二)公共科目笔试成绩同时达到拟调剂职位和原报考职位的合格分数线,且考试类别相同。 拟调剂职位设置了专业科目笔试条件的,专业科目笔试成绩还须同时达到合格分数线,且考试类别相同。 (三)未进入原报考职位面试人员名单。

58

2026.01.15

国考成绩查询入口 国考分数公布时间2026
国考成绩查询入口 国考分数公布时间2026

笔试成绩查询入口已开通,考生可登录国家公务员局中央机关及其直属机构2026年度考试录用公务员专题网站http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/examResult/written_result.html,查询笔试成绩和合格分数线,点击“笔试成绩查询”按钮,凭借身份证及准考证进行查询。

11

2026.01.15

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

65

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

36

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

75

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

21

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

35

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.7万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 7万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号