引出

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

数组,布尔值?

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

返回了个 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. Kettle的概念学习系列之Kettle是什么?(一)

    不多说,直接上干货! Kettle是什么? Kettle是一款国外开源的ETL工具,纯java编写,可以在Window.Linux.Unix上运行,绿色无需安装,数据抽取高效稳定. Kettle 中文 ...

  2. quartz.net定时任务框架详解

    C#做定时任务:一是Timer:而是Quartz.net:本文就学习一下Quartz.net框架 Quartz.net非常的灵活,开发人员能用很少的代码就能完成“每隔一小时执行”.“每天2点执行”.“ ...

  3. 准备把平台挪到linux

    在上午准备周末胡老师的课程考核的Ppt时,逐渐我觉得不得不把平台挪到linux了.很多并行的应用不只是在linux上效率更高,而且很多包都在linux上.另外如果不及早挪到Linux上,后面遇到的问题 ...

  4. vue中使用viewerjs

    项目创建 插件Viewer.js vue init webpack mytest001 安装viewerjs npm install viewerjs 删掉生成的项目里面的helloWord.vue ...

  5. Axios 使用时遇到的问题

    最近使用 vue 构建一个小项目,在使用 axios 发送 post 请求的时候,发现 axios 发送数据默认使用 json 格式,百度搜了下,更改 ContentType 不管用,最终问题原来是: ...

  6. 紫书 例题 10-2 UVa 12169 (暴力枚举)

    就是暴力枚举a, b然后和题目给的数据比较就ok了. 刘汝佳这道题的讲解有点迷,书上讲有x1和a可以算出x2, 但是很明显x2 = (a * x1 +b) 没有b怎么算x2?然后我就思考了很久,最后去 ...

  7. 紫书 习题 8-16 UVa 1618 (中途相遇法)

    暴力n的四次方, 然而可以用中途相遇法的思想, 分左边两个数和右边两个数来判断, 最后合起来判断. 一边是n平方logn, 合起来是n平方logn(枚举n平方, 二分logn) (1)两种比较方式是相 ...

  8. ajax前台传到后台乱码,显示问号的问题

    response.setContentType("text/html;charset=gbk"); response.setHeader("Cache-Control&q ...

  9. Qt之QPushButton

    简述 前面章节我们分享过Qt之QAbstractButton,讲解了QAbstractButton的基本用法,本节着重讲解QPushButton. 简述 常用状态 效果 源码 QSS 更多参考 关于Q ...

  10. spark一些入门资料

    spark一些入门资料 A Scala Tutorial for Java Programmers http://docs.scala-lang.org/tutorials/scala-for-jav ...