乐趣区

关于php:学习PDO中的错误与错误处理模式

在 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

参考文档:

https://www.php.net/manual/zh/pdo.error-handling.php

===========

各自媒体平台均可搜寻【硬核项目经理】

退出移动版