php异常处理的深入

引出

如果你调一个类,调用时数据验证时报了个错,你会以什么方式返回

数组,布尔值?

数组这个可以带错误原因回来,那布尔值呢?

返回了个 false, 报错时把错误放在类变量里?
还是专门用一个获取错误的方法进行获取?

上面说的情况是代码完全没有问题的情况。
那如果是一些第三方的工具包,你又怎么知道他里面的执行会不会导致整个系统崩溃。

你说本地运行是没问题的,环境这种东西不好说。

所以我们就用到了 异常 这个东西

下面是我们需要了解的问题

什么时候抛异常?怎么接异常?异常要怎么处理?他的使用场景又是什么?

基础知识

  1. 基础操作

    try ... catch()
    throw

  2. 错误级别

    致命错误 E_ERROR,
    语法错误 E_PARSE,
    警告错误 E_WARNING,
    通知错误 E_NOTICE

  3. php异常处理类

预定义异常

    * ErrorException (extends Exception)

SPL异常类

    * LogicException (extends Exception)      // 表示程序逻辑中的错误的异常。这种异常应该直接在代码中的修复* BadFunctionCallException            // 回调调用未定义的函数或缺少一些参数时会抛出该异常* BadMethodCallException          // 回调方法是一个未定义的方法或缺失一些参数时会抛出该异常* DomainException                     // 值不遵守定义的有效数据域时会抛出该异常* InvalidArgumentException            // 参数不是预期类型时会抛出该异常* LengthException                     // 长度无效时会抛出该异常* OutOfRangeException                 // 请求非法索引时引发的异常,这应该在编译时就检测到的错误* RuntimeException (extends Exception)    // 在运行时发生的错误会抛出该异常* OutOfBoundsException                // 值不是有效键时会抛出该异常,这表示在编译时无法检测到的错误* OverflowException                   // 在向完整容器中添加元素时引发的异常* RangeException                      // 在程序执行期间为指示范围错误而引发的异常。通常这意味着除了/overflow以外还有一个算术错误。这是运行时的DomainException版本* UnderflowException                  // 在空容器上执行无效操作(如删除元素)时引发的异常* UnexpectedValueException            // 值与一组值不匹配时会抛出该异常。通常,当一个函数调用另一个函数并期望返回值为某种类型或值(不包括算术或缓冲区相关错误)时,就会发生这种情况
  1. 异常处理相关函数
    error_reporting // 设置报告的错误级别register_shutdown_function // 注册一个会在php中止时执行的函数set_error_handler // 设置用户自定义的错误处理函数set_exception_handler // 设置用户自定义的异常处理函数error_get_last // 获取最后发生的错误

使用场景

  1. 系统

    主要抓的是无法预测的错误,统一返回,没有使用 try...catch 接收的异常直接跳进设置的方法中

<?phpnamespace App\Exception;use Exception;/*** 异常句柄(入口)类*/
class Handler
{// 默认错误处理public static function errorHandler($errno, $errstr, $errfile = '', $errline = 0){}// 默认异常处理public static function exceptionHandler($ex){try {throw $ex;} catch (Order $e) {echo "订单异常";} catch (Goods $e) {echo "商品异常";} catch (User $e) {echo "用户异常";} catch (Exception $e) {echo "其他异常";}}// 致命错误处理public static function fatalErrorHandler(){if ($e = error_get_last()) {print_r($e);}}
}/*** 订单异常*/
class Order extends Exception
{
}/*** 商品异常*/
class Goods extends Exception
{
}/*** 用户异常*/
class User extends Exception
{
}
<?php
// 入口文件中error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);register_shutdown_function(array('App\\Exception\\Handler', 'fatalErrorHandler'));set_error_handler(array('App\\Exception\\Handler', 'errorHandler'));set_exception_handler(array('App\\Exception\\Handler', 'exceptionHandler'));
  1. 工具

    定义自定义的异常,一有错误直接抛出。使用工具的程序只需通过 Exception 接收异常即可, 所有异常都通过这个进行处理的

<?phpnamespace Testlin\Db\Exception;use Exception;interface ExceptionInterface
{
}class Db extends Exception implements ExceptionInterface
{
}class Pdo extends Db
{
}
?><?php
namespace Testlin\Db;use Exception;
use Testlin\Db\Exception\Pdo;class Db
{protected $db;public function __construct($config){$this->db = new PDO($config);if ($this->db == false) {throw new Pdo("连接失败");}}
}?>

文章例子

  1. 工具包例子
  2. 项目例子

FQA

1、为什么要定自定义异常类, 系统不是已经给了很多选择,而且很多 composer 包里都只是继承一下。

答:其实自定义异常是为了用区分异常颗粒度的,比如

我定了 订单异常,商品异常,用户异常 类,但是 订单里的异常多种多样,比如订单支付异常,订单生成异常。

* RuntimeException (extends Exception)* Order* Paymen* Created* Goods* User* Withdraw

当项目抛出异常时

<?phptry {$param = []; // 操作那个方法时传的参数throw App\Exception\Order\Payment::forParam('执行xxx操作异常', $param);} catch (Exception $e) {// 相关操作get_class($e); // 当前异常类 App\Exception\Order\Payment}

通过异常类名,我们可以知道是订单支付异常。这里可以代替错误号,而且更清晰明了

2、为什么有一些 composer 包里的自定义异常,有的有很多方法。有什么用处吗?

作用1:格式化异常

比如:抛出的异常提示是 "id=xx 的用户不存在",我们会有以下两种写法

<?php// 普通操作
$id = 1;
throw new Payment("id={$id} 的用户不存在");// 格式化异常
use App\Exception\Order;class Payment extends Order
{public static function forId($id){return new self(sprintf('id=%s 的用户不存在',$id));}
}$id = 1;
throw Payment::forId($id);

作用2:组件级别的异常

<?phpnamespace Testlin\Db\Exception;use Exception;interface ExceptionInterface
{
}class Mysqli extends Exception impements ExceptionInterface
{
}class Pdo extends Exception impements ExceptionInterface
{
}try {throw new Testlin\Db\Exception\Mysqli('sql 执行失败');
} catch (Testlin\Db\Exception\ExceptionInterface $e) {// 这里取得的异常只会是继承这个接口的异常// 可以只针对这个工具包进行处理
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281795.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hadoop/HDFS命令

Hadoop中文手册&#xff1a;http://hadoop.apache.org/docs/r1.0.4/cn/commands_manual.html 英文手册&#xff1a;http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/CommandsManual.html Hadoop fs命令 hadoop fs: 该命令可以用于其他文件系统&#x…

内置IOC容器ServiceCollection

.NetCore内置IOC容器ServiceCollection一、IOC介绍IOC&#xff1a;全名(Inversion of Control)-控制反转IOC意味着我们将对象的创建控制权交给了外部容器&#xff0c;我们不管它是如何创建的&#xff0c;我们只需要知道&#xff0c;当我们想要某个实例时&#xff0c;我们可以直…

React+Redux仿Web追书神器

引言 由于 10 月份做的 React Native 项目没有使用到 Redux 等库&#xff0c;写了一段时间想深入学习 React&#xff0c;有个想法想做个 demo 练手下&#xff0c;那时候其实还没想好要做哪一个类型的&#xff0c;也看了些动漫的&#xff0c;小说阅读&#xff0c;聚合资源的开源…

windows配置solr5.5.2(不通过tomcat,使用内置jetty)

一、windows下配置solr5.5.2(不通过tomcat,使用内置jetty) 第一步&#xff1a;安装Jdk1.7 Solr5.5好像只支持Jdk1.7及以上的版本&#xff0c;没亲测&#xff0c;solr6.0是只支持jdk1.8及以上的&#xff0c;下图为启动solr时的截图&#xff1a; 如何在windows环境下配置jdk及验证…

【C# Personal Handbook】运行环境

一、CLR、CLI、CTS、CLS、BCL、FCL简介CLI&#xff08;公共语言基础&#xff09;CLI是微软公司向ECMA提交的一份语言和数据格式规范&#xff0c;CLR是目前为止唯一一个公共语言基础的实现版本。CLI包括了公共类型系统&#xff08;CTS&#xff09;、公共中间语言&#xff08;CIL…

如何完善自己的知识结构

★领域 &#xff08;本来想用“学科”这个词&#xff0c;后来觉得“学科”的范畴还是偏小&#xff0c;就改用“领域”&#xff09;  按照传统的习惯&#xff0c;通常会把知识归类到不同的领域&#xff08;比如&#xff1a;文学、数学、计算机、烹调、等等&#xff09;。 ◇领…

java调c++代码_Java中调用C++代码的实现 | 学步园

JNI为 Java Native Interface 即Java本地接口&#xff0c;使用此种方式可以对C/C代码进行调用&#xff0c;其在本质上是对C/C生成的动态库进行调用而不是直接对C/C代码进行调用Java代码如下&#xff1a;public class TestJNI{//JNI在本质上是调用C/C的动态库来实现的&#xff…

jeesite1.X 集成多数据源

2019独角兽企业重金招聘Python工程师标准>>> 网上看了几个例子&#xff0c;都是相同数据源的动态切换&#xff0c;如果不是同一种数据库类型&#xff0c;分页查询就出问题。经过研究解决问题。 jeesite.properties配置多数数据源地址,这里以mysql5.7和sqlserver2008…

k8s HPA(HorizontalPodAutoscaler)-自动水平伸缩

Horizontal Pod Autoscaling in Kubernetes写在前面我们平时部署web服务&#xff0c;当服务压力大撑不住的时候&#xff0c;我们会加机器(加钱)&#xff1b;一般没有上容器编排是手动加的&#xff0c;临时加的机器&#xff0c;临时部署的服务还要改Nginx的配置&#xff0c;最后…

spark java 逻辑回归_逻辑回归分类技术分享,使用Java和Spark区分垃圾邮件

原标题&#xff1a;逻辑回归分类技术分享&#xff0c;使用Java和Spark区分垃圾邮件由于最近的工作原因&#xff0c;小鸟很久没给大家分享技术了。今天小鸟就给大家介绍一种比较火的机器学习算法&#xff0c;逻辑回归分类算法。回归是一种监督式学习的方式&#xff0c;与分类类似…

jQuery.extend()方法

定义和用法jQuery.extend()函数用于将一个或多个对象的内容合并到目标对象。 注意&#xff1a; 1. 如果只为$.extend()指定了一个参数&#xff0c;则意味着参数target被省略。此时&#xff0c;target就是jQuery对象本身。通过这种方式&#xff0c;我们可以为全局对象jQuery添加…

Wget用法、参数解释的比较好的一个文章

一个语句就可以下载cvpr2016的全部论文&#xff1a; wget -c -N --no-clobber --convert-links --random-wait -r -p -E -e robotsoff -U mozilla http://www.cv-foundation.org/openaccess/CVPR2016.py 其中&#xff0c;-c表示断点续传&#xff1b;-N表示已经下载的内容不再重…

.NET VS智能提示汉化 (.Net6)

先上现成的.net6汉化文件&#xff0c;可以手动下载后参照 [如何为 .NET 安装本地化的 IntelliSense 文件 ](https://learn.microsoft.com/zh-cn/dotnet/core/install/localized-intellisense)进行安装。或者使用后文的工具进行自动安装。无对照英文在前中文在前汉化内容来自 官…

老人寻求到一名程序员,用2W行代码给自己打造了一幅肖像画

今天翻墙看了下国外的论坛&#xff0c;看到了一位版主给一位老人描绘肖像画的文章&#xff0c;不得不说这位大佬是真的厉害&#xff0c;近20000行代码&#xff0c;而且还画的很像&#xff0c;像小编我这种手残党&#xff0c;用笔也不能画出来&#xff0c;不得不服&#xff0c;今…

一题多解,ASP.NET Core应用启动初始化的N种方案[下篇]

[接上篇]“天下大势&#xff0c;分久必合&#xff0c;合久必分”&#xff0c;ASP.NET应用通过GenericWebHostService这个承载服务被整合到基于IHostBuilder/IHost的服务承载系统中之后&#xff0c;也许微软还是意识到Web应用和后台服务的承载方式还是应该加以区分&#xff0c;于…

GitHub服务中断24小时11分钟事故分析报告\n

上周&#xff0c;GitHub经历了一次事故&#xff0c;导致服务降级24小时11分钟。虽然平台的某些部分不受事故影响&#xff0c;但仍然有多个内部系统受到了影响&#xff0c;向用户显示了过时且不一致的内容。所幸没有用户数据丢失&#xff0c;但针对几秒钟数据库写入的手动调整工…

php 合并 字符串_PHP如何去重合并字符串

本篇文章主要给大家介绍PHP如何去重合并字符串。推荐教程&#xff1a;《PHP教程》对于PHP学习者来说&#xff0c;合并多个字符串&#xff0c;应该并不是很难。但是如果这多个字符串中&#xff0c;有相同元素&#xff0c;当我们想要合并他们并且要使其值具有唯一值。也就是说合并…

软概(lesson 2):课堂测试

一、测试题目 二、完成过程 1.设计思想 ①连接mysql数据库 ②设计user类&#xff0c;增加参数 ③设计add类&#xff0c;向数据库内增加内容 ④设计addInput页面&#xff0c;完成录入操作 ⑤设计add页面&#xff0c;接收录入的参数&#xff0c;并调用add类函数 2.源代码 user.ja…

谷歌Gboard输入法新增“无痕模式”:仅在Chrome隐身窗口中适用

据外媒Android Police报道&#xff0c;如大家所知道的&#xff0c;Chrome浏览器中的“隐身模式”是为了防止你的私密浏览记录被其他人看到&#xff0c;但是&#xff0c;在这种模式下&#xff0c;你的输入法键盘依然会记住你输入的短语&#xff0c;为了阻止你的键盘在Chrome隐身…

php两个数组融合,php合并两个数组的方式有哪些

1、arrary_merge示例代码&#xff1a;$arr1 array(1, 2, 3, 4, 5);$arr2 array(1, 2, 6, 7, 8, 9, 10);$result1 array_merge($arr1, $arr2);$arr3 array("name" > "itbsl", "age" > 13, "sex" > "Male");$arr…