2019年8月23日10:56:31
php很多开发不习惯使用异常处理,因为web开发,重在于快速开发,易用性,高性能,不强调程序健壮性
php的异常使用其实不是太完善,易用性也差点,当然这个对比其他语言来说
比较标准的做法就是先划分错误类型,分别针对错误类型制订处理方案和机制
比如业务逻辑级别错误,系统级别错误,致命错误等,针对不同级别错误,处理错误,增强代码的健壮性和访问友好性
class LogicException extends Exception{ //重定义构造器使第一个参数 message 变为必须被指定的属性 public function __construct($message, $code=0){ //可以在这里定义一些自己的代码 //建议同时调用 parent::construct()来检查所有的变量是否已被赋值 parent::__construct($message, $code); } public function __toString() { //重写父类方法,自定义字符串输出的样式 return __CLASS__.":[".$this->code."]:".$this->message."<br>"; } public function customFunction() { //为这个异常自定义一个处理方法 echo "按自定义的方法处理出现的这个类型的异常<br>"; } }
在最终错误返回的时候,针对具体错误类型做处理
Controller
public function test(Request $Request) { try { return response()->json(['code' => 200, 'msg' => '操作成功', 'data' => $data]); } catch (Exception $e) { dealErr($e); }
function dealErr(Exception $e) { if ($e instanceof LogicException) { } elseif ($e instanceof Exception) { } else { throw new Exception('未知错误异常'); } //获取请求参数 request()->all(); //写入日志 Log::info(); //返回信息 return response()->json(['code' => 400, 'msg' => $e->getMessage(), 'error' => formaErr($e)]); }
下面是一个比较常用的demo
OrderController
public function getSonSaleOrderPay(Request $Request) { try { $page = parameterCheck($Request->page, 'int', 1); $pageSize = parameterCheck($Request->page_size, 'int', 15); $parent_order_key = parameterCheck($Request->parent_order_key, 'string', ''); $data = SaleParentOrderService::getSonOrderPay(parent::$shop_id, $parent_order_key, $page, $pageSize); return response()->json(['code' => 200, 'msg' => '操作成功', 'data' => $data]); } catch (Exception $e) {
return response()->json(['code' => 400, 'msg' => $e->getMessage(), 'error' => formaErr($e)]);
} }
SaleParentOrderService
public static function getSonOrderPay(int $shop_id, string $parent_order_key, int $page = 1, int $pageSize = 15) { try { $SaleOrder = SaleOrder::where('is_delete', 10)->where('shop_id', $shop_id)->where('parent_order_key', $parent_order_key)->where('order_category', 20)->first(); if (empty($SaleOrder)) { throw new Exception('父订单号错误or订单数据被删除'); } $SaleOrderArray = SaleOrder::where('is_delete', 10)->where('shop_id', $shop_id)->where('parent_order_key', $parent_order_key)->where('order_category', 20)->get(); if (empty($SaleOrderArray)) { return ['total' => 0, 'list' => []]; } } catch (Exception $e) { throw $e; } }
//格式化错误信息,方便输出 function formaErr(Exception $e) { // if ($e instanceof Exception == false) { // throw new Exception('数据类型错误'); // } $msg['File'] = $e->getFile(); $msg['Line'] = $e->getLine(); $msg['Msg'] = $e->getMessage(); $msg['Trace'] = $e->getTraceAsString(); return $msg; }
注意这 是自己 throw 不然laravel会抛出就会返回不友好,特别是get请求的时候,
我个人是希望php引入java throws,这样在多层级别代码的时候,可以减少很多不必要的逻辑代码的编写,直接往上层扔,方便易用
public static void function() throws NumberFormatException{ }
关于多层嵌套的try catch finally任何捕捉异常的方法
php在处理多层嵌套的时候回多余两层处理的时候,catch不能直接捕捉深层的跑出的异常只能 finally处理,但是有时候在多层抛出的异常是作为消息提示,getMessage方法的信息
处理方法也很简单因为抛出只能是上层异常对象才能处理,只需要在下层吧异常信息打包重新发给上一层就可以捕捉了
try { } catch (Exception $e) { // throw $e; throw new Exception($e->getMessage()); }
有一点蛋疼但是有时候也没办法,这样多层嵌套的时候依然可以捕捉到具体抛出的错误信息