引出

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

数组,布尔值?

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

返回了个 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 // 值与一组值不匹配时会抛出该异常。通常,当一个函数调用另一个函数并期望返回值为某种类型或值(不包括算术或缓冲区相关错误)时,就会发生这种情况

<ol><li>异常处理相关函数</li></ol>
error_reporting // 设置报告的错误级别
register_shutdown_function // 注册一个会在php中止时执行的函数
set_error_handler // 设置用户自定义的错误处理函数
set_exception_handler // 设置用户自定义的异常处理函数
error_get_last // 获取最后发生的错误

<h2>使用场景</h2>
<ol><li>系统<p>主要抓的是无法预测的错误,统一返回,没有使用 try...catch 接收的异常直接跳进设置的方法中</p>
</li></ol>

<?php

namespace 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'));


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

<?php

namespace 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-&gt;db = new PDO($config); if ($this-&gt;db == false) {
throw new Pdo("连接失败");
}
}

}

?>


<h2>文章例子</h2>
<ol>
<li><a href="https://github.com/test-lin/pack_demo" rel="nofollow noreferrer">工具包例子</a></li>
<li><a href="https://github.com/test-lin/project_demo" rel="nofollow noreferrer">项目例子</a></li>
</ol>
<h2>FQA</h2>
<p>1、为什么要定自定义异常类, 系统不是已经给了很多选择,而且很多 composer 包里都只是继承一下。</p>
<p>答:其实自定义异常是为了用区分异常颗粒度的,比如</p>
<p>我定了 订单异常,商品异常,用户异常 类,但是 订单里的异常多种多样,比如订单支付异常,订单生成异常。</p>
  • RuntimeException (extends Exception)

    • Order

      • Paymen
      • Created
    • Goods
    • User
      • Withdraw

<p>当项目抛出异常时</p>

<?php

try {

$param = []; // 操作那个方法时传的参数

    throw App\Exception\Order\Payment::forParam('执行xxx操作异常', $param);
} catch (Exception $e) {
// 相关操作
get_class($e); // 当前异常类 App\Exception\Order\Payment
}

<p>通过异常类名,我们可以知道是订单支付异常。这里可以代替错误号,而且更清晰明了</p>
<p>2、为什么有一些 composer 包里的自定义异常,有的有很多方法。有什么用处吗?</p>
<p><strong>作用1:格式化异常</strong></p>
<p>比如:抛出的异常提示是 "id=xx 的用户不存在",我们会有以下两种写法</p>

<?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);


<p><strong>作用2:组件级别的异常</strong></p>

<?php

namespace 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) {

// 这里取得的异常只会是继承这个接口的异常

// 可以只针对这个工具包进行处理

}



原文地址:https://segmentfault.com/a/1190000016824772

php异常处理的深入的更多相关文章

  1. 关于.NET异常处理的思考

    年关将至,对于大部分程序员来说,马上就可以闲下来一段时间了,然而在这个闲暇的时间里,唯有争论哪门语言更好可以消磨时光,估计最近会有很多关于java与.net的博文出现,我表示要作为一个吃瓜群众,静静的 ...

  2. 基于spring注解AOP的异常处理

    一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...

  3. 异常处理汇总 ~ 修正果带着你的Net飞奔吧!

    经验库开源地址:https://github.com/dunitian/LoTDotNet 异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983 ...

  4. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  5. IL异常处理

    异常处理在程序中也算是比较重要的一部分了,IL异常处理在C#里面实现会用到一些新的方法 1.BeginExceptionBlock:异常块代码开始,相当于try,但是感觉又不太像 2.EndExcep ...

  6. Spring MVC重定向和转发以及异常处理

    SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...

  7. 【repost】JS中的异常处理方法分享

    我们在编写js过程中,难免会遇到一些代码错误问题,需要找出来,有些时候怕因为js问题导致用户体验差,这里给出一些解决方法 js容错语句,就是js出错也不提示错误(防止浏览器右下角有个黄色的三角符号,要 ...

  8. 札记:Java异常处理

    异常概述 程序在运行中总会面临一些"意外"情况,良好的代码需要对它们进行预防和处理.大致来说,这些意外情况分三类: 交互输入 用户以非预期的方式使用程序,比如非法输入,不正当的操作 ...

  9. 关于bug分析与异常处理的一些思考

    前言:工作三年了,工作内容主要是嵌入式软件开发和维护,用的语言是C,毕业后先在一家工业自动化控制公司工作两年半,目前在一家医疗仪器公司担任嵌入式软件开发工作.软件开发中,难免不产生bug:产品交付客户 ...

  10. ABP(现代ASP.NET样板开发框架)系列之23、ABP展现层——异常处理

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之23.ABP展现层——异常处理 ABP是“ASP.NET Boilerplate Project (ASP.NET ...

随机推荐

  1. 关于lncRNA数据收集

    最近需要自己收集数据库里的核酸序列,于是直接面对一些神文 http://www.360doc.com/content/17/0120/08/30227855_623625901.shtml http: ...

  2. POJ 3723 Conscription (Kruskal并查集求最小生成树)

    Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14661   Accepted: 5102 Des ...

  3. 51nod 1098 最小方差 排序+前缀和+期望方差公式

    题目: 题目要我们,在m个数中,选取n个数,求出这n个数的方差,求方差的最小值. 1.我们知道,方差是描述稳定程度的,所以肯定是着n个数越密集,方差越小. 所以我们给这m个数排个序,从连续的n个数中找 ...

  4. php获取当前月份的前(后)几个月

    //获取当前月份的前一月 function GetMonth($sign) { //得到系统的年月 $tmp_date=date("Ym"); //切割出年份 $tmp_year= ...

  5. vue反向代理解决跨域

    问题描述 在项目开发的时候,接口联调的时候一般都是同域名下,且不存在跨域的情况下进行接口联调,但是当我们现在使用vue-cli进行项目打包的时候,我们在本地启动服务器后,比如本地开发服务下是 http ...

  6. 【BZOJ1014】【JSOI2008】火星人prefix

    题意: Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 ...

  7. 地图底图的类型——MapView,SceneView

    MapView用于创建二维地图平面. 引用“esri/Map”,"esri/views/MapView" 具体做法并举例:var map = new Map({basemap:&q ...

  8. vue项目的webpack4.X配置

    这两天摆弄webpack,躺过很多坑,直到今天看了一位博主的文章才得以解决.他对配置中的各个部分做说明. 下面的配置99.9%抄自博主: https://www.cnblogs.com/nianyif ...

  9. LightOJ-1074 Extended Traffic 最短路问题 注意连通性

    题目链接:https://cn.vjudge.net/problem/LightOJ-1074 题意 给一图 求最短路 若最短路<3或没有最短路,则输出'?' 思路 首先注意到可能存在负环,所以 ...

  10. 浅谈 MySQL的外键的作用

    MySQL中外键的介绍: MySQL外键必须使用存储引擎为  innDB  其中MySAM 和MEMORYH这两种引擎不支持 由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据的 ...