PDOException 异常处理|学习笔记

简介: 快速学习 PDOException 异常处理

开发者学堂课程【PHP 进阶教程-由浅入深掌握面向对象开发-第三阶段PDOException 异常处理】学习笔记,与课程紧密联系,让用户快速学习知识。  

课程地址:https://developer.aliyun.com/learning/course/713/detail/12742


PDOException 异常处理

 

1、目标

本节目标掌握PDO中异常的实际使用,能够使用这种PDO的异常机制来封装代码的一个异常处理。

2、概念

PDOException:是PDO从exception继承的一个用于专门用于处理PDO中错误的异常类,一般如果做一套扩展都会去继承Exception来实现一套明确的错误机制(错误来自哪里),哪里我们要去做这件事情,然后要使用PDOException异常处理需要,设定PDO的错误模式为异常模式。

在PDO中可以通过两种模式来实现异常模式的设定。

(1):在初始化PDO对象的时候,利用第四个参数驱动来实现

(2):在初始化PDO之后,利用PDO::set Attribute()方法来修改错误模式。

3、步骤

演示具体步骤:

(1):第一个确定使用PDO异常来处理错误。

(2)第二个设定错误模式为异常模式

(3)第三个关键点,在可能出现错误的地方捕捉异常,使用PDOException类来实现。

4、示例

具体的示例:

设定异常模式,利用PDO::_construct()构造方法的第四个参数或者在实例化PDO之后,利用PDO::set Attribute()方法设置。

先使用构造方法的第一种方式:

$drivers=array(

#可以设置多种驱动(属性设置)

PDO::ATT_ERRMODE=> PDO::ERRMODE_EXCEPTION

);$pdo=newPDO(_’mysql:host=locallhost;port=3306;dbname=db_2’’root’,’root’,$drivers);

//增加一个驱动,里面增加一个属性,属性的下标,为PDO::ATT_ERRMODE,然后指向PDO::ERRMODE_EXCEPTION这个定义常量,把它弄好之后,放到我们的第四个参数里面就可以实现。下面编写代码进行实际操作:第一步实例化,用这种初始化的方式增加一个属性,其实就相当于它做完之后,后续做了一个PDO::set Attribute,即错误模式等于异常模式(PDO::ATT_ERRMODE= PDO::ERRMODE_EXCEPTION),这样就得到了一个异常模式的PDO,后续的所有操作它都应该是用异常来捕捉错误,确定了使用异常模式处理之后,其实就可以针对出错的位置使用异常来进行捕捉。比如在执行 SQL 的时候,很有可能会出现这种异常处理,比如要设置字符集,假设没在上面做,这个时候需要调用exec执行SQL,SQL属于人为可写的,通常这个字符集的来源是外部传入的,那么不能保证它的完全正确,怎么办呢?异常捕捉,但是捕捉都必须使用try catch来捕捉,捕捉好了之后,就使用PDO::ERRMODE_EXCEPTION类的对象来进行具体的处理,因为它报出的错误都会是产生一个PDO::ERRMODE_EXCEPTION的对象,来证明一下,把这个代码复制过来放到指定地方进行运行:

#执行SQL

try{

$pdo->exec(‘set names utf-8’); #错误

}catch(PDOException $e){

echo ‘SOL执行错误!<br/>‘;

echo ‘错误文件为:’.$e->getFile().’<br/>’;

echo ‘错误行号为:’.$e->getLine().’<br/>’;

echo ‘错误描述为:’.$e->getMessage();die();

}

//凡是执行SQL的地方,都有可能出现异常,用set names utf-8进行捕捉,看一下效果:

image.png这个时候就按照我们的指定的方式来做的,这就是异常模式,那当然可以做得更优雅的处理,不是这样直接报错,因为用户无所谓,那么作为开发阶段,可以用这种方式。但是如果是生产阶段,就是我们投入使用了,就应该写入到错误日志一样,供我们运维的人,或者说开发的人来实现这种什么判定或者说错误的一个检查,修正我们的一个代码,那这个我们就知道应该怎么用,如果说这个地方本身假设我抛出的一个throw new Exception(‘异常’)这样的异常,出现的效果:

image.png

它是把这个变成警告模式了,并没有去按照我们的方式来处理,是因为产生的这个exception类的一个对象,但是你这边捕获的却是一个PDO的,相当于它的一个子类的对象,你是捕获不到的。但是如果说我们这个地方再换一个,再换一个思路,把catch(PDOException $e)改为catch(Exception $e),观察能否捕获到。image.png

结果是可以捕获到,那个这又是什么样的逻辑?

image.png原因其实很简单,PDOException类的一个对象,本身是从Exception这里面继承的,所以它本身也是属于Exception对象,是跟它相关的,因此上级捕获下级可以捕获,但是如果是下级捕获上级,那么就捕获不了,所以这是它们的一个过程,在实际使用的时候,肯定是,谁报的什么对象错误,用什么来捕获,我们就用哪个地方来捕获这个数据,并且处理。那么从PDO的一个执行来讲,pdo异常模式的设置是在PDO实例化之后,但如果PDO实例化的时候就错误,那么PDOException就无法工作,因为我们先实例化PDO,然后再相当于设置了它的模式为异常模式,那么我们的PDO开发团队也其实考虑这个问题,PDO实例化之后本身是可以用try{]catch(){]来捕获的,我们要做的事情是使用先天异常捕捉实例化的错误,加一个try。

try{$pdo=newPDO(_’mysql:host=locallhost;port=3307;dbname=db_2’’root’,’root’,$drivers);

}catch(PDOException $e){

echo ‘实例化PDO错误!<br/>’;

echo ‘错误文件为:’.$e->getFile().’<br/>’;

echo ‘错误行号为:’.$e->getLine().’<br/>’;

echo ‘错误描述为:’.$e->getMessage();

die();

}

#执行SQL

try{

$pdo->exec(‘set names utf-8’); #错误

}catch(PDOException $e){

echo ‘SOL执行错误!<br/>‘;

echo ‘错误文件为:’.$e->getFile().’<br/>’;

echo ‘错误行号为:’.$e->getLine().’<br/>’;

echo ‘错误描述为:’.$e->getMessage();

die();

}

如果把3306改为3307。

image.png

运行之后的结果:image.png显示实例化PDO错误,同时出现了一个很典型的问题,报出乱码错误信息,应该是什么积极拒绝之类的信息,那说明这个信息依然有可能是中文,应该怎么办?把echo ‘错误描述为:’.$e->getMessage();

改为echo ‘错误描述为:’.iconv($e->getMessage());通过这个其实也可以思考一下,PDO的底层应用的是什么,用的是一套跟my SQL i扩展一样的一套底层来实现的。所以没有注意到这个中文问题,echo ‘错误描述为:’.iconv($e->getMessage());改ech’o错误描述 为:’.iconv(_’gbk’,’utf-8’,$e->getMessage());,再一刷新,看一下效果:

image.png乱码部分显示积极拒绝,所以这个地方要注意细节的问题,细节问题描述一下,因为连接错误,还没有设置好字符集,系统返回的信息字符集为GBK。做好之后我们该做的事情,其他的该捕获就捕获,但是在捕获的过程中,有时还要考虑一个问题,如果业务真的没有办法往下面执行,意外逻辑无法继续,可以主动抛出异常,就是throw new PODException,比如说我们在写的过程中,我们执行的操作执行完之后发现,我要获取他的ID这个业务需求,而获取的时候发现没做到,那么我们该怎样?应该抛出这个异常,因为外部用这个ID肯定用来干事情的,我没有拿到,我应该怎么把这个东西给他,怎么样给他抛出来,去捕获这个数据,这就是我们的一个主动抛出异常。

#抓异常

try{

$pdo->exec(‘insert into t_40 values’);

$id = $pdo->lastInsertID();

If(!$id) throw new PDOException(‘没有拿到自增ID:插入失败’);

}catch(PDOException $e){

echo ‘SOL执行失败!<br/>‘;

echo ‘错误文件为:’.$e->getFile().’<br/>’;

echo ‘错误行号为:’.$e->getLine().’<br/>’;

echo ‘错误描述为:’.$e->getMessage();

die();

}

这个是主动捕捉异常,判定数据执行的时候,发现逻辑问题无法继续。或者说无法为后面的一个业务提供支持了,我们就应该让他报错,前面的代码都让它变好之后,后面他能不能主动起来,这个代码是可以放到一起try,没必要try这么多次,我们会发现,这个代码都可能有错,可以放在一起try。

image.png运行结果如下图:

image.png分析一下,捕获到了错误信息,语法错误首先捕捉到了,是因为这个地方是不是本身有问题,如果是我们操作的过程中本身成功了,成功了,但是没有注册ID,比如说我当前是个‘select *from t_40’_操作就捕获一下,结果显示没有ID,因为这个逻辑它可以执行,只是它拿到的是一个行数,不要让它得到一个PDO的对象,所以没办法往下面真正地获取数据,这样可以主动控制,这是我们的一个逻辑。

总结:

1、PDOException是用来捕捉异常PDO(PDOStatement)类使用过程中产生的错误的

2、PDOException在使用之前必须要开启PDO异常模式,否则不能使用。其实PDO的实例化除外,因为它必须是最开始操作,所以系统考虑过它可以直接步骤,

3、像这种异常处理的模式有类似的相关性,会发现我们在处理的时候是不是给我一个对象,然后把错误捕获起来,那如果很多地方都用到try catch,进行封装直接调用即可,维护统一且方便。

4、PDOException一般是在SQL执行过程中出错,因为内部执行通常不会出现太多错误。不外乎就是你外部给的SQL有问题,或者你的逻辑有问题,让我出现错误,所以如果出现这种业务的话,我们应该怎么主动抛出异常,让他在往上面执行,因为它有可能支撑不了后续的业务。

相关文章
|
网络协议 安全 Android开发
软件丨李跳跳们现在该如何跳呢?
前段时间,李跳跳等软件被某大厂发了律师函,之后,好些个跳广告软件都相继发布公众号说明,停止维护软件,并且下架了相关软件,那我们还能跳吗?该怎么跳呢?
1485 0
软件丨李跳跳们现在该如何跳呢?
|
缓存
npm install 一直卡着不动如何解决
npm install 一直卡着不动如何解决
7984 0
|
JavaScript
uniapp如何获取IP地址
uniapp如何获取IP地址
2192 0
|
JavaScript
vue项目获取本机局域网IP地址
局域网下获取本机 IP 地址方便访问 vue 项目
3240 0
|
1月前
|
SQL
SQL语言深入理解: GROUP_CONCAT()函数详细介绍
总结一下, `GROUP_CONCAT()` 是一个非常强大的函数,在处理复杂查询和报告时非常有用。它提供了一种简单有效的方法来连接和显示多行数据。
381 0
|
网络安全
虚拟机三种网络模式
虚拟机三种网络模式
|
11月前
|
Go 数据库
Go语言中的包(package)是如何组织的?
在Go语言中,包是代码组织和管理的基本单元,用于集合相关函数、类型和变量,便于复用和维护。包通过目录结构、文件命名、初始化函数(`init`)及导出规则来管理命名空间和依赖关系。合理的包组织能提高代码的可读性、可维护性和可复用性,减少耦合度。例如,`stringutils`包提供字符串处理函数,主程序导入使用这些函数,使代码结构清晰易懂。
394 11
|
人工智能 自然语言处理 搜索推荐
10分钟构建AI客服:阿里云技术解决方案评测
在数字化转型的浪潮中,企业对客户服务的即时性和个性化需求愈发迫切。阿里云推出的“10分钟构建AI客服并应用到网站、钉钉、微信中”的技术解决方案,为企业提供了一个快速、低成本的AI客服部署方案。本文将从部署流程、用户体验、成本效益等方面对这一方案进行深入评测。
1173 3
|
SQL PHP 数据库
19 PHP如何利用PDO获取结果集
路老师在知乎上分享了关于PHP语言的知识,帮助大家入门并深入了解PHP。本文介绍了PDO中获取结果集的三种方法:`fetch()`、`fetchAll()` 和 `fetchColumn()`,并通过具体案例展示了如何使用这些方法从数据库中获取数据并展示在网页上。
475 5
|
缓存 监控 Linux