引出

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

数组,布尔值?

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

返回了个 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) {// 这里取得的异常只会是继承这个接口的异常// 可以只针对这个工具包进行处理
}

php异常处理的深入相关推荐

  1. Go语言的错误异常处理机制及其应用

    一.背景 在日常编写golang程序或阅读别人的golang代码时,我们总会看到如下的一堆代码块: xx, err = func(xx) if err != nil {//do sth. to tac ...

  2. SpringBoot (二) :全局异常处理设置

    说在前面 在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler.@InitBinder.@ModelAttribute,并应用到所有 ...

  3. 2021年大数据常用语言Scala(三十四):scala高级用法 异常处理

    目录 异常处理 捕获异常 抛出异常 异常处理 Scala中 无需在方法上声明异常 来看看下面一段代码. def main(args: Array[String]): Unit = {val i = 1 ...

  4. Java基础(七)--Exception异常处理

    发现错误的理想时机是程序运行之前(编译期),然后不太现实,很多异常无法被发现(特别是业务上的数据),需要在运行时解决. 错误恢复机制保证代码健壮性的方式,异常处理在程序中很常见,也是必须的,必须考虑有 ...

  5. 零基础学习python_异常处理(32-33课)

    我们写完python执行的时候是不是经常会遇到报错,而且报错都是大片红字,这样给别人的感受就是你写的程序怎么老是出问题啊,这样我们还咋么混下去呢?于是乎,就有了异常处理的东东. python的try语 ...

  6. Spring Security 实战干货:自定义异常处理

    Spring Security 实战干货:自定义异常处理 转自:https://www.cnblogs.com/felordcn/p/12142514.html 文章目录 1. 前言 2. Sprin ...

  7. C++ 笔记(20)— 异常处理(抛出异常、捕获异常)

    异常提供了一种转移程序控制权的方式. C++ 异常处理涉及到三个关键字: try . catch . throw . throw : 当问题出现时,程序会抛出一个异常.这是通过使用 throw 关键字 ...

  8. recover 没有捕获异常_GO语言异常处理机制panic和recover分析

    本文实例分析了GO语言异常处理机制panic和recover.分享给大家供大家参考.具体如下: Golang 有2个内置的函数 panic() 和 recover(),用以报告和捕获运行时发生的程序错 ...

  9. ssm 异常捕获 统一处理_SSM 统一异常处理

    SSM 统一异常处理 spring创建中, 处理异常可以使用try-cache处理, 也可以使用spring提供的统一异常处理 在spring中, 统一处理异常有2中方式 注解方式 @Exceptio ...

  10. java 异常的分类并举例_Java异常处理中的一些特殊情况举例

    只使用try和finally不使用catch的原因和场景JDK并发工具包中,很多异常处理都使用了如下的结构,如AbstractExecutorService,即只有try和finally没有catch ...

最新文章

  1. WKWebView 那些坑
  2. Sentinel 发布里程碑版本,添加集群流控功能
  3. oracle 基础1
  4. 研究死锁–第5部分:使用显式锁定
  5. Python基础(六)--类与对象
  6. 如何实现RTMP推送Android Camera2数据
  7. (100)详细描述一个你做过的项目, 面试必问(二十四)(第20天)
  8. Mycat安全权限配置privileges---MyCat分布式数据库集群架构工作笔记0032
  9. mysql导出数据库方法_mysql导出数据库几种方法
  10. 质点碰撞和卢瑟福公式
  11. 在设备上启用开发者选项
  12. word文档通配符换行_Word应用分隔符的使用
  13. 冯绍峰晒与韩寒片场邋遢照 自称工地领薪水
  14. Python Tox 使用笔记
  15. 【EasyRL学习笔记】第五章 Proximal Policy Optimization 近端策略优化算法
  16. 如何在本地搭建FTP服务器以及搭建后的用途
  17. springboot多数据源如何配置驼峰映射或配置文件不起作用的问题
  18. js中onsubmit用法
  19. 给阿里云域名解析添加CAA记录,防止你的域名证书被劫持
  20. DEVC++的几个实用小技巧

热门文章

  1. 图片的base64编码实现以及网页上显示
  2. 图解 React-router 源码
  3. Vue Router 4.0 正式发布!焕然一新。
  4. Java之泛型T T与T的用法
  5. linux中/usr下文件权限修改setuid导致的问题
  6. 选择 GCD 还是 NSTimer ?
  7. 2016年Web前端面试题
  8. Angular - - angular.element
  9. Mac升级到Yosemite后默认的php版本不支持imagetfftext函数问题解决
  10. 移动web开发(一)——移动web开发必备知识