欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

学习PDO中的错误与错误处理模式

程序员文章站 2022-03-10 11:38:55
在 PDO 的学习过程中,我们经常会在使用事务的时候加上 try...catch 来进行事务的回滚操作,但是大家有没有注意到默认情况下 PDO 是如何处理错误语句导致的数据库操作失败问题呢?今天,我们就来学习一下。 PDO 中的错误与错误处理模式简介 PDO 提供了三种不同的错误处理方式: PDOE ......

在 pdo 的学习过程中,我们经常会在使用事务的时候加上 try...catch 来进行事务的回滚操作,但是大家有没有注意到默认情况下 pdo 是如何处理错误语句导致的数据库操作失败问题呢?今天,我们就来学习一下。

pdo 中的错误与错误处理模式简介

pdo 提供了三种不同的错误处理方式:

  • pdo::errmode_silent,这是 pdo 默认的处理方式,只是简单地设置错误码,可以使用 pdo::errorcode() 和 pdo::errorinfo() 方法来检查语句和数据库对象

  • pdo::errmode_warning,除设置错误码之外,pdo 还将发出一条传统的 e_warning 信息。如果只是想看看发生了什么问题且不中断应用程序的流程,那么此设置在调试/测试期间非常有用。

  • pdo::errmode_exception,除设置错误码之外,pdo 还将抛出一个 pdoexception 异常类并设置它的属性来反射错误码和错误信息。

原来默认情况下,我们的 pdo 是不会处理错误信息的,这个你知道吗?如果不信的话,我们继续向下看具体的测试情况。不过,首先我们要说明的是,pdo 的错误处理机制针对的是 pdo 对象中的数据操作能力,如果在实例化 pdo 对象的时候就产生了错误,比如数据库连接信息不对,那么直接就会抛出异常。( php5 中会直接返回一个 null,php7会抛出异常! )

$pdo = new pdo('mysql:host=127.0.0.1;port=3306;dbname=blog_test1', 'root', '');
// fatal error: uncaught pdoexception: sqlstate[hy000] [1049] unknown database 'blog_test1'

blog_test1 表并不存在,所以在 new pdo 的时候就已经直接会抛出异常了。这个在实例化连接数据库过程中的错误处理机制是固定的,不是我们能修改的错误处理机制,毕竟如果连数据库连接都无法建立的话,就不用谈后面的任何操作了。

默认情况

$pdo = new pdo('mysql:host=127.0.0.1;port=3306;dbname=blog_test', 'root', '');
$pdo->query('select * from aabbcc');
var_dump($pdo->errorcode());
// string(5) "42s02"

var_dump($pdo->errorinfo());
// array(3) {
//   [0]=>
//   string(5) "42s02"
//   [1]=>
//   int(1146)
//   [2]=>
//   string(38) "table 'blog_test.aabbcc' doesn't exist"
// }

在上面的测试代码中,我们查询了 aabbcc 这个表,但其实数据库中并不存在这个表。如果不使用 errorcode() 或者 errorinfo() 的话,这段代码不会有任何输出,也就是说,不会有任何错误信息让你看到,代码就直接运行过去了。

这个就是 pdo 在默认情况下的错误处理机制。其实,这样的处理并不好,因为如果我们忘记设置错误处理机制的话,就会导致一些错误无法呈现,而且并不好调试。

设置为警告

$pdo->setattribute(pdo::attr_errmode, pdo::errmode_warning);
$pdo->query('select * from aabbcc');
// warning: pdo::query(): sqlstate[42s02]: base table or view not found: 1146 table 'blog_test.aabbcc' doesn't exist

在设置错误处理机制为警告后,pdo 会抛出一个不影响程序执行的 warning 信息。但是,如果我们修改了 ini 文件中错误处理机制后,也可能是看不到警告信息的。不过相对于默认处理的情况来说,有一条警告信息已经非常好了。

设置为异常

$pdo->setattribute(pdo::attr_errmode, pdo::errmode_exception);
$pdo->query('select * from aabbcc');
// fatal error: uncaught pdoexception: sqlstate[42s02]: base table or view not found: 1146 table 'blog_test.aabbcc' doesn't exist 

最后,我们将错误处理机制设置为抛出异常。总算是能让程序中止运行并且报出 fatal error 错误了,同时,这个异常信息也是可以通过 try...catch 来捕获到的。这样的开发才是我们最需要的开发形式。

属性添加方式

在上述测试代码中,我们使用的是 setattribute() 方法来设置 pdo 的错误处理属性,但其实我们可以在实例化 pdo 类时就指定一些需要的属性。

$pdo = new pdo('mysql:host=127.0.0.1;port=3306;dbname=blog_test', 'root', '', [pdo::attr_errmode => pdo::errmode_warning]);
$pdo->query('select * from aabbcc');
// warning: pdo::query(): sqlstate[42s02]: base table or view not found: 1146 table 'blog_test.aabbcc' doesn't exist

总结

pdo 已经是现在的主流数据库连接扩展,也是各种框架的必备连库扩展,但是如果不深入的学习的话,很多人可能还真不知道很多关于 pdo 的一些知识。框架在为我们带来便利的同时,也让我们变得更“笨”,所以,学习还是要更多地接触底层地知识,免得在面试的时候需要手写代码的时候手足无措。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202008/source/%e5%ad%a6%e4%b9%a0pdo%e4%b8%ad%e7%9a%84%e9%94%99%e8%af%af%e4%b8%8e%e9%94%99%e8%af%af%e5%a4%84%e7%90%86%e6%a8%a1%e5%bc%8f.php

参考文档:

===============

关注公众号:【硬核项目经理】获取最新文章

添加微信/qq好友:【xiaoyuezigonggong/149844827】免费得php、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

b站id:482780532