当前位置: 首页 > 后端技术 > PHP

学习PDO中的错误和错误处理方式

时间:2023-03-29 20:51:14 PHP

在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=newPDO('mysql:host=127.0.0.1;port=3306;dbname=blog_test1','root','');//Fatalerror:UncaughtPDOException:SQLSTATE[HY000][1049]Unknowndatabase'blog_test1'blog_test1表不存在,所以新建PDO时会直接抛出异常。这种在实例化和连接数据库过程中的错误处理机制是固定的,不是我们可以修改的错误处理机制。毕竟如果不能建立数据库连接,后面的操作就更不用说了。默认$pdo=newPDO('mysql:host=127.0.0.1;port=3306;dbname=blog_test','root','');$pdo->query('select*fromaabbcc');var_dump($pdo->errorCode());//字符串(5)"42S02"var_dump($pdo->errorInfo());//数组(3){//[0]=>//字符串(5)"42S02"//[1]=>//int(1146)//[2]=>//string(38)"Table'blog_test.aabbcc'doesn'texist"//}在上面的测试代码中,我们查询了aabbcc表,但数据库中实际不存在该表。如果不使用errorCode()或errorInfo(),这段代码不会有任何输出,也就是没有错误信息给你看,代码直接运行。这是PDO的默认错误处理机制。其实这样处理并不好,因为如果我们忘记设置错误处理机制,有些错误就不会显示出来,也不好调试。设置警告$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);$pdo->query('select*fromaabbcc');//警告:PDO::query():SQLSTATE[42S02]:Basetableorviewnotfound:1146Table'blog_test.aabbcc'doesn'texist将错误处理机制设置为warning后,PDO会抛出不影响程序执行的警告信息。但是,如果我们修改ini文件中的错误处理机制,我们可能就看不到警告信息了。不过相比默认的处理方式,有警告信息就很好了。设置为异常$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);$pdo->query('select*fromaabbcc');//Fatalerror:UncaughtPDOException:SQLSTATE[42S02]:Basetableorviewnotfound:1146Table'blog_test.aabbcc'doesn'texist最后,我们将错误处理机制设置为抛出异常。最后,程序可以停止运行并报告Fatalerror错误。同时,这个异常信息也可以通过try...catch来捕获。这种发展是我们最需要的发展形式。属性添加方法在上面的测试代码中,我们使用setAttribute()方法来设置PDO的错误处理属性,但实际上我们可以在实例化PDO类的时候指定一些需要的属性。$pdo=newPDO('mysql:host=127.0.0.1;port=3306;dbname=blog_test','root','',[PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING]);$pdo->query('select*fromaabbcc');//Warning:PDO::query():SQLSTATE[42S02]:Basetableorviewnotfound:1146Table'blog_test.aabbcc'doesn'texist摘要PDO是现在主流的Databaseconnectionextension,也是各种框架必备的库扩展,但是如果不深入研究,很多人可能真的对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参考文档:https://www.php.net/manual/zh/pdo.error-handling.php=============各媒体平台均可搜索【硬核项目经理】