正确的处理PHP异常

刚开始接触PHP的时候没有意识到异常的重要性,有时候出问题很难精确的找到问题点,正确的处理异常也是一门学问

异常的类别
PHP7异常做了很多变动,异常类 Exception 和错误类 Error 都实现了 Throwable 接口

结构如下:

Throwable

ClosedGeneratorException

DOMException

ErrorException

IntlException

LogicException

PharException

ReflectionException

RuntimeException

SodiumException

BadMethodCallException

BadFunctionCallException

DomainException

InvalidArgumentException

LengthException

OutOfRangeException

OutOfBoundsException

OverflowException

PDOException

RangeException

UnderflowException

UnexpectedValueException

ArithmeticError

AssertionError

ParseError

TypeError

DivisionByZeroError

ArgumentCountError

Error

Exception

什么时候才需要抛异常
这个一切从实际出发,如果你觉得你的代码可能会出现问题,就可以进行抛出异常

如何捕获异常
PHP中使用 try…catch…finally 捕获异常

public function test(){ try { //可能出错的代码逻辑
} catch (\Exception $e) { echo $e->getMessage();
} finally { //todo
}
}
如果不确定出现异常还是错误,可以直接捕获 Throwable 异常

public function test(){ try { //可能出错的代码逻辑
} catch (\Throwable $e) { echo $e->getMessage();
} finally { //todo
}
}
业务场景实战
现在的项目很多都是前后端分离、restful风格接口的设计进行开发。现在我就用tp5框架来进行实战下在实际业务中是如何优雅的使用异常的

场景描述
选择一个比较简单的业务场景,以登录模块为例,用户在移动端进行登录时,需要进行登录,注册,忘记密码,获取手机验证码等接口。

构建约束条件
登录
入参:

用户手机号

用户密码

手机验证码

约束:

用户手机号不能为空,格式正确,且此用户确实是存在的

密码不能为空,密码格式正确

手机验证码不能为空,且是在有效期内的

注册
入参:

用户手机号

用户密码

密码二次确认

手机验证码

约束:

用户手机号不能为空,格式正确,且此用户确实是新用户,系统不存在此用户信息

密码不能为空,密码格式正确

二次密码要跟密码一样

手机验证码不能为空,且是在有效期内的

忘记密码:
入参:

用户手机号

用户新密码

密码二次确认

手机验证码

约束:

用户手机号不能为空,格式正确,且此用户确实是存在的

密码不能为空,密码格式正确

二次密码要跟密码一样

手机验证码不能为空,且是在有效期内的

获取手机验证码
入参:

用户手机号

约束:

用户手机号不能为空,格式正确

一分钟内只能获取一次

自定义tp5异常
创建异常处理Handle类

application\lib\exception\ExceptionHandlenamespace application\lib\exception;use Exception;use think\exception\Handle;class ExceptionHandle extends Handle{ /**

 * @var $httpStatusCode http状态码
 */
private $httpStatusCode;    
/**
 * @var $msg 错误信息
 */
private $msg;     
/**
 * @var $code 错误码
 */
private $code;    # 自定义错误异常需要重写tp5父类的这个render方法
public function render(Exception $e)
{        if ($e instanceof BaseException) {            # 自定义异常
        $this->httpStatusCode = $e->httpStatusCode;            $this->msg = $e->msg;            $this->code = $e->code;
    } else {            # 系统异常
        //TODO记录错误日志
        return parent::render($e)
    }
    
    $result = [            'code' => $this->code,            'msg' => $this->msg
    ];        # 返回给前端
    return json($result, $this->httpStatusCode);

}
创建基础的异常类

application\lib\exception\BaseExceptionnamespace application\lib\exception;use think\Exception;# 异常类需要继承tp5的异常基类class BaseException extends Exception{ public $httpStatusCode = 401; public $msg = ‘parameter error’;

public $code = 10000;    
public function __construct(array $params = [])
{        if (array_key_exists('httpStatusCode', $params)) {            $this->httpStatusCode = $params['httpStatusCode'];
    }        
    if (array_key_exists('msg', $params)) {            $this->msg = $params['msg'];
    }        
    if (array_key_exists('code', $params)) {            $this->code = $params['code'];
    }
    
}

}
创建具体异常类
参数错误异常类

namespace app\lib\exception;class ParameterException extends BaseException{ public $httpStatusCode = 200; public $msg = ‘parameter error’; public $code = 10000;
}
用户不存在

class UserNotExistsException extends BaseException{ public $httpStatusCode = 200; public $msg = ‘user is not exists’; public $code = 20000;
}
如何使用
我们先来看看登录这个功能

传统处理方法
public function login($phone, $password){
$uid = t h i s − > g e t U i d B y P h o n e ( this->getUidByPhone( this>getUidByPhone(phone); if (!KaTeX parse error: Expected '}', got '#' at position 15: uid) { #̲ 进行处理 } } 通…phone, $password){
$uid = t h i s − > g e t U i d B y P h o n e ( this->getUidByPhone( this>getUidByPhone(phone); if (!$uid) { # 抛出异常,返回给前端
throw new UserNotExistsException();
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值