详解PHP中的PDO类
时间:2018-12-30 分类:PHP 作者:编程之家
简介
咱一起来看看PDO类。PDO是PHP Data Objects的缩写,它被描述为“在PHP 中访问数据库 的轻量级,兼容性的接口”。尽管它的名字不咋好听,但PDO是一个 在PHP 中访问数据库 会让人喜爱的方式。
与MysqL i的不同
MysqL i和PDO很相似,都有两方面主要区别:
1.MysqL i只能访问MysqL ,但PDO可以访问12种不同的数据库
2.PDO没有普通函数 调用 (MysqL i_*functions)
开始步骤
首先,你得确定一下你的PHP 是否安装了PDO插件 。你可以用$test=new PDO()的结果来测试。如果提示 说是参数不匹配,那证明已经安装了PDO插件 ,如果说是对象不存在,你得先确认一下在pho.ini中PHP _pdo_youRSS qlserverhere.extis是否被注释掉了。如果没有这句话,那你得安装了,这里就不啰嗦了。
连接
现在我们确认服务器已经工作,开始连接数据库吧:
' . $e);
}
除$dsn之外,所有语句和变量都能自我解释。DSN指的是数据源名称,有多种输入类型。最常见的一种是我们刚刚用的这种,PHP官网解释了 。
你可以省去DSN的其他额外参数,只需要在数据库 驱动后面带个冒号,比如(MysqL :)。在这 种情况下PDO将会尝试连接到本地数据库 。就像当你使用MysqL i时需要在查询 中指定数据库 名称 一样。
最后一件你需要注意的事情就是我们用try-catch块包裹了我们的初始化对象。PDO连接失败的时候将会抛出PDOException异常而不是查询 失败的时候。如果你愿意你可以使用下面代码 $db=line来选择异常的模式。
setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
或者你可以直接在PDO初始化时传递参数:
PDO::ERRMODE_EXCEPTION
));
我们现在使用的是错误 的方式——在失败时候简单返回false,我们是没有理由不对异常进行处理的。
在PDO中使用query和exec两种方法 使得对数据库 查询 变得非常简单。如果你想得到查询 结果的行数exec是非常好用的,因此对SELECT查询 语句是非常有用的。
现在我们通过下面的一个 例子查看这两种方法 :
rush:
PHP ;">
$statement = <<
$foods = $db->query($statement);
假设我们的查询 是正确的,$foods现在是一个 PDO Statement对象,我们可以用它获取 到我们的结果或者是查看这次查询 中一共查到多少条结果集。
行数
不足的是,PDO没有提供一个 统一的方法 去计算返回的行数。PDO Statement包含了一个 叫做rowCount的方法 ,但是这个方法 却不能保证在每一个 sql 驱动中起作用(幸运的是,它能够在MysqL 数据库 中起作用)。
如果你的sql 驱动不支持 这个方法 ,你也有2个选择:使用二次查询 (SELECT COUNT(*))或者使用简单的count($foods)得到行数。
幸运的是对我们的MysqL 例子,我们可以使用下面的简单方法 来输出 正确的行数。
rowCount();
遍历结果集
打印出这些可口的食物一点也不困难:
FetchAll() as $food) {
echo $food['name'] . ' ';
}
唯一需要注意的是PDO也支持 Fetch方法 ,这个方法 只会返回第一条结果,这对于只需要查询 一条结果集是非常有用的。
转义用户 输入(的特殊字符)
你可曾听说过(MysqL i_)real_escape_string,这是用于确保用户 输入安全数据。PDO提供了一个 方法 叫做quote,这个方法 可以把输入字符串中带有引号的地方进行特殊字符转义。
rush:
PHP ;">
$input: this is's' a '''pretty dange'rous str'ing
在转义后,最终得到下面结果:
quote($input): 'this is\'s\' a \'\'\'pretty dange\'rous str\'ing'
exec()
正如上面提到的,你可以使用exec()方法 实现UPDATE,DELETE和INSERT 操作,执行后它会返回受影响行数的数量 :
rush:
PHP ;">
$statement = <<
echo $db->exec($statement); // outputs number of deleted rows
预处理语句
尽管exec方法 和查询 在PHP 中仍然被大量使用和支持 ,但是PHP 官网上还是要求大家用预处理语句的方式来替代。为什么呢?主要是因为:它更安全。预处理语句不会直接在实际查询 中插入参数,这就避免了许多潜在的sql 注入。
然而出于某种原因,PDO实际上并没有真正的使用预处理,它是在模拟预处理方式,在将语句传给sql 服务器之前会把参数数据插入到语句中,这使得某些系统容易受到sql 注入。
如果你的sql 服务器不真正的支持 预处理,我们可以很容易的通过如下方式在PDO初始化时传参来修复这个问题:
setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
接下来开始我们的第一个 预处理语句吧:
prepare('SELECT * FROM foods WHERE `name`=? AND `healthy`=?');
$statement2 = $db->prepare('SELECT * FROM foods WHERE `name`=:name AND `healthy`=:healthy)';
正如你所见,有两种创建参数的方法 ,命名的与匿名的(不可以同时出现在一个 语句中)。然后你可以使用bindValue来敲进你的输入:
bindValue(1,'Cake');
$statement->bindValue(2,true);
$statement2->bindValue(':name','Pie');
$statement2->bindValue(':healthy',false);
注意使用命名参数的时候你要包含进冒号(:)。PDO还有一个 bindPara m方法 ,可以通过引用绑定数值,也就是说它只在语句执行的时候查找相应数值。
现在剩下的唯一要做 的事情,就是执行我们的语句:
execute();
$statement2->execute();
// Get our results:
$cake = $statement->Fetch();
$pie = $statement2->Fetch();
为了避免只使用bindValue带来的代码 碎片,你可以用数组给execute方法 作为参数,像这样:
execute(array(1 => 'Cake',2 => true));
$statement2->execute(array(':name' => 'Pie',':healthy' => false));
事务
前面我们已经描述过了什么是事务:
一个 事务就是执行一组查询 ,但是并不保存他们的影响到数据库 中。这样做的好处是如果你执行了4条相互依赖的插入语句,当有一条失败后,你可以回滚使得其他的数据不能够插入到数据库 中,确保相互依赖的字段能够正确的插入。你需要确保你使用的数据库 引擎支持 事务。
开启事务
你可以很简单的使用beginTransaction()方法 开启一个 事务:
beginTransaction();
$db->inTransaction(); // true!
然后你可以继续执行你的数据库 操作语句,在最后提交事务:
commit();
还有类似MysqL i中的rollBack()方法 ,但是它并不是回滚所有的类型(例如在MysqL 中使用DROP TABLE),这个方法 并不是真正的可靠,我建议尽量避免依赖此方法 。
其他有用的选项
有几个选项你可以考虑用一下。这些可以作为你的对象初始化时候的第四个参数输入。
$options = array($option1 => $value1,$option[..]);
$db = new PDO($dsn,$options);
PDO::ATTR_DEFAULT_FETCH_MODE
你可以选择PDO将返回的是什么类型的结果集,如PDO::FETCH_ASSOC,会允许你使用$result['column_name'],或者PDO::FETCH_OBJ,会返回一个 匿名对象,以便你使用$result->column_name
你还可以将结果放入一个 特定的类(模型),可以通过给每一个 单独的查询 设置一个 读取模式,就像这样:
query('SELECT * FROM `foods`');
$foods = $query->fetchAll(PDO::FETCH_CLASS,'Food');
PDO::ATTR_ERRMODE
上面我们已经解释过这一条了,但喜欢TryCatch的人需要用到:PDO::ERRMODE_EXCEPTION。如果不论什么原因你想抛出PHP警告,就使用PDO::ERRMODE_WARNING。
PDO::ATTR_TIMEOUT
当你为载入时间而着急时,你可以使用此属性来为你的查询指定一个超时时间,单位是秒. 注意,如果超过你设置的时间,缺省会抛出E_WARNING异常,除非 PDO::ATTR_ERRMODE 被改变.
更多属性信息可以在 里查看到.
最后的思考
PDO是一个 在PHP 中访问你的数据库 的很棒的方式,可以认为是最好的方式。除非你拒绝使用面向对象的方法 或是太习惯 MysqL i 的方法 名称 ,否则没有理由不使用PDO。
更好的是完全切换到只使用预处理语句,这最终将使你的生活更轻松!
原文地址:https://www.jb51.cc/php/21582.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。