捕获异常_TP6异常捕获机制,HTTP请求异常原理解析,常见问题分享

作为国人开发的PHP框架。目前已更新至TP6。但是对于TP6的到来,在底层上面和TP5又是不一样的变化,我后续将不断的带来框架底层的分享。

异常机制大家在项目都会使用到,但对于框架的异常原理你知道吗? 以及框架里面有错误但是它就是不抛出来,直接500服务错误。如何解决呢?

一、TP6异常有那些类型

TP6的对PHP版本是>7.1.0

2da41dac39b39be609784e634e966e1b.png

所以框架底层的异常捕获是继承了Throwable错误异常接口。所以整个框架都是基于该接口来操作的。可能有的小伙伴说,一般异常捕获不是用Exception吗?为什么是Throwable呢?

那是因为Exception类是实现了Throwable接口,从而来方面我们调用。接口如果不实现它有用吗?实现流程:TP框架的Exception类继承PHP底层Exception类,底层类再去实现Throwable接口

注:Throwable可参加上一篇文章PHP7错误异常

TP6共用8大异常类型,在vendoropthinkframeworksrchinkexception下面:

7511512c6c6b27354d795a186705ac18.png
分别是:错误异常、文件异常、系统异常、HTTP异常、HTTP响应异常、非法数据异常、路由异常、数据验证异常

其中ErrorException是错误异常,这也是为什么像PHP的语法错误框架可以捕获的原因。

75690220d9e4a1b24fa70c58770b5f5b.png

而大家常用的Exception类来抛出异常,它就会去实现该PHP底层错误异常类,而像ErrorException也会去实现Exception基类。所以大家可以把它理解为应用逻辑操纵的基类。而像Http、Route、Valide它们会去继承PHP底层的RuntimeException

RuntimeException照样会继承Exception

7527d7ffcbcb4f1a02a5634bc7b0d6df.png

RuntimeException类的继承方式

33b450c7fa5af9389f003f7d7be2e105.png
经常使用的getMessage、getFile等方法都是来源于我们的Throwable接口
070b229897e39402171e158b1b4b79c8.png

二、异常捕获的原理解析

TP6框架有2中方式,分为手动与自动捕获。手动捕获异常是基于try-catch结构来进行捕获。例如:

try { echo 44; throw new Exception('我是手动抛出来的');} catch (Exception $e) { // 这是进行异常捕获 return json($e->getMessage());}//执行结果:44"我是手动抛出来的"

注意:PHP异常是不抛出不执行的,这里的手动抛出是指,当我们throw抛出后。它会在下面的Catch里面进行捕获。而不是说你都不 throw new Exception对象。就可以在下面捕获到异常

抛出异常就是去执行 了tp的定义的Exception类,也就是我们在框架目录下面的vendoropthinkframeworksrchinkException.php类

1766267a7d36f3de7a8f93feb9c924b6.png

那自动是怎么实现的呢?

自动实现是我们再去启动框架的时候会把它自动的注入到容器里面并绑定关系的。一开始是没有,当运行后就会绑定起来。

cd75be861cf3de43e0ebcce0d69eeaaf.png
绑定后的关系,array_merge是合并多个数组为一个。如果有多个关系就合并用一个来绑定。最终就有thinkexceptionHandle=>appExceptionHandle 的关系

这也是为什么TP6已经默认实现其全局的自动异常类,你可以不用再去实现了。而这个实现的类就是appExceptionHandle类库。也就是框架里面绑定的服务实例都会在框架载入的来启动。

f0fb542703224745e4dcec0546f2dee1.png

那这个自动方式 也需要调用方法啊?你不调用怎么执行呢?

当我们绑定实例化关系后,然后再绑定实例给容器后,我们就会去执行HTTP请求,它就是HTTP下面去捕获我们异常的。

9c2b36077945d417987685573ca865c1.png

看到了吗?,当我们去执行请求的时候,如果有异常抛出,那就会被Throwable接口管理到。接口的触发就是在于类库去实现了接口的,这个 比较好理解。然后我们就会调用前面注册到容器里面的Handle::class--->report()方法

三、框架应用错误不抛出的解决方案

框架应用的错误不抛出是在于框架默认只是去捕获HTTP请求的处理,而不会作用于应用。所以如果是你应用下面出现问题,它是抛不出来,这个大家后面写代码的时候一定要去注意到,不然到时候就尴尬了

例如:配置文件Log.php有语法错误,但是你去访问方法的时候就直接报500,而不是抛出异常,如果你的应用配置接口不对也是一样的

ce702b4d5f70dd86ebfb9e5acf650629.png

那这个是怎么造成的呢?

这个是因为在我们去执行请求实现自动抛出的时候,需要在容器里面去反转实例,当我们的错误应用错误的时候,我们就会进行Error的错误注册机制里面去捕获,它 不是属于普通错误异常捕获机制。而在应用错误捕获,我们是把错误信息打印到控制台上,所以它不会输出到我们浏览器上面

a8883bb7c5d90d462be8a4ae8d9e152b.png

如何解决:大家可以用debug来调试下,就可以看到他直接打印到控制台上

希望大家有收获,对于框架源码解析。我会不定期更新。大家可以留言或者关注发私信。我会根据大家意见来更新技术文章。

年轻就要折腾

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TP(ThinkPHP)框架的路由解析原理可以简单概括为以下三个步骤: 1. 获取请求信息:TP框架通过PHP的超全局变量`$_SERVER`和`$_REQUEST`获取当前请求的URL、请求方法等信息。 2. 解析路由规则:TP框架会根据路由规则解析当前请求的控制器、方法以及传递给方法的参数。路由规则可以通过配置文件或者注解方式定义。 3. 执行控制器方法:TP框架根据解析出来的控制器、方法和参数,执行相应的业务逻辑。 具体来说,TP框架的路由解析过程如下: 1. 获取请求信息: TP框架通过`$_SERVER`变量获取当前请求的URL和请求方法,例如: ``` $requestUri = $_SERVER['REQUEST_URI']; // 获取请求的URL $requestMethod = $_SERVER['REQUEST_METHOD']; // 获取请求的方法 ``` 2. 解析路由规则: TP框架支持多种路由规则,例如: - URL模式:`/:controller/:action/:id`,解析后会得到控制器名、方法名和参数`id`; - 路由规则:`'user/:id' => 'index/user/read'`,将`user/123`请求解析为`Index`控制器的`user`方法,并传递参数`id=123`; - 注解方式:使用注解标记控制器和方法,例如: ```php /** * @route('hello/:name') */ public function hello($name) { echo 'Hello '.$name; } ``` 以上是TP框架路由的基本使用方法,具体可以参考官方文档。 3. 执行控制器方法: TP框架根据解析出来的控制器名、方法名和参数,执行相应的业务逻辑。例如: ```php // 根据控制器名和方法名,实例化控制器对象并调用方法 $controller = '\\app\\index\\controller\\'.$controllerName; $instance = new $controller(); $instance->$actionName($param); ``` 注意,TP框架还支持路由缓存等优化方式,可以提高路由解析效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值