0

0

如何优雅的使用异常

php中文网

php中文网

发布时间:2016-06-20 12:33:56

|

1155人浏览过

|

来源于php中文网

原创

老子曰:程序开发时,有 80% 的代码在处理各种异常。

由于php实在是太过于灵活简单,很多phper对异常的处理其实不太感冒,于是乎,我们会经常看到

die("xxx");

exit("xxx");

这样的异常处理,但这类异常对于项目的稳定性却很不友好,主要有以下几点问题:

1:粗暴的打断正常的业务流。

2:调试非常因难。

3:灵活度太差

那我们展开来看这三个问题:

1:现代的框架,大都有一个标准的处理流程:

_before();  //前置控制器,可以做一个数据的初始化

run();      //业务逻辑的处理

_after();   //后置控制器,在处理完业务,有机会进行收尾(比如回收资源,统一打日志等)。

但如果的 业务逻辑处理里(run)直接用 exit, die这类函数会直接退出php当前脚本的执行,从而跳过_after(),这显然不符合正常的逻辑。

2:笔者曾经有个经历,打开某个页面,突然白屏,经过一翻苦苦的debug,终于在某处发现了一个孤零零的exit,没有任何提示,碰到这样的代码,对于调试者来说,就是个噩梦。

3:现在已经不再是pc互联网的时候,移动互联网比例已大幅增加,这时,我们往往是输出一个接口,如果直接碰到exit, die这类输出可能直接导致客户端崩溃。

那正确的使用方式是什么?

没错,就是php自带的Exception, php自带的Exception非常的强大而且友好,可能由于历史原因,很多人没有习惯使用它。

所以,针对第一个问题,我们在进行框架设计的时候,就可以这么处理:

try {

$ctrl->_before();

$ctrl->$method();

$ctrl->_after();

} catch (\Exception $e) {

$ctrl->_atfer(); //让_after在异常后也能正常执行

throw $e;        //再抛出异常

}

抛出异常之后, 通过Exception类自带的 getTrace()方法,可以获得调用栈,这样就能很方便的进行调试。

最后可以通过set_exception_handler自定义异常处理,最终输出正确的数据格式。

帖上一小段我常用的异常处理代码。

假定我们的api代码约定:

{

code: 0,   //非0表示异常

msg:  "",  //提示信息,非0时有值

data: {}   //code=0时的业务数据,

}

自定义异常处理类

class MyException extends \Exception

{

public $realCode = '';

public function __construct($message, $code = -1)

{

$this->realCode = $code;

parent::__construct($message, $code);

}

public static function exceptionHandler(\Exception $exception)

{

$model = ZFormater::exception($exception);            //格式化异常

Log::info([\var_export($model, true)], 'exception');  //异常写日志

淘客帝国免费版
淘客帝国免费版

淘客帝国免费版4.3,整合JSSDK,开放屏蔽词设置,优化效率。,感谢大家对淘客帝国的支持,因为有你们的支持,让我们不断前进,不断完善.淘客帝国团队向各位淘客致谢~我们一直在努力争取给淘客朋友们提供最好的淘客TOP API淘客程序!免费版我们一如既往会一直更新,希望大家关注免费版的最新版本号。随时保持版本更新。 请仔细用10分钟时间查看以下信息!本程序以官方名义推荐。没有任何后门,大家可放心使用!

下载

$info = array();

if(property_exists($exception, 'realCode')) {

$codeArr = explode('_', $exception->realCode);

if(count($codeArr) > 1) {

$model['code'] = intval($codeArr[0]);

$model['msg'] = $codeArr[1];

}

}

if ($config['debug_mode']) {                          //调式模式,输出调用栈

$info['debug'] = $model;

}

$info['msg'] = $model['message'];

$info['ret'] = empty($model['code']) ? -1 : $model['code'];

if(Request::isAjax()) {                              //ajax请求,json串输出

Request::setViewMode('Json');

}

if('Php' == Request::getViewMode()) {               //页面请求,统一的异常页面展示

if ($config['debug_mode']) {

Request::setTplFile('public/exception.php');

} else {

Request::setTplFile('public/error.php');

}

}

Response::display($info);

}

realCode对应的定义:

class ERROR

{

const DEF_MSG = '系统异常';

//系统级异常码

const PARAM_ERROR = '1_参数异常';

const NEED_LOGIN =  '2_需要登录';

const USER_ERROR =  '3_用户名不存在';

const PASS_ERROR =  '4_密码异常';

}

然后通过set_exception_handler("MyException::exceptionHandler"); 进行自定义异常处理后,我们在业务层,碰到异常的逻辑,就可以统一的、愉快的进行下面这样的异常抛出了:

throw new MyException('param xxx error', ERROR::PARAM_ERROR);

那么最终输出的api将会是:

{

"code": 1,

"msg":  "参数异常"

}

这样就可以和exit, die 说再见了。

PS: 以上代码大都取自zphp框架,详细可参考ZPHP框架: https://github.com/shenzhe/zphp

--------------伟大的分割线----------------

PHP饭米粒(phpfamily) 由一群靠谱的人建立,愿为PHPer带来一些值得细细品味的精神食粮!

本文由 桶哥 原创,转载请注明本来源信息和以下的二维码(长按可识别二维码关注):

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

39

2026.02.06

java多线程方法汇总
java多线程方法汇总

本专题整合了java多线程面试题、实现函数、执行并发相关内容,阅读专题下面的文章了解更多详细内容。

17

2026.02.06

1688阿里巴巴货源平台入口与批发采购指南
1688阿里巴巴货源平台入口与批发采购指南

本专题整理了1688阿里巴巴批发进货平台的最新入口地址与在线采购指南,帮助用户快速找到官方网站入口,了解如何进行批发采购、货源选择以及厂家直销等功能,提升采购效率与平台使用体验。

289

2026.02.06

快手网页版入口与电脑端使用指南 快手官方短视频观看入口
快手网页版入口与电脑端使用指南 快手官方短视频观看入口

本专题汇总了快手网页版的最新入口地址和电脑版使用方法,详细提供快手官网直接访问链接、网页端操作教程,以及如何无需下载安装直接观看短视频的方式,帮助用户轻松浏览和观看快手短视频内容。

150

2026.02.06

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

11

2026.02.06

Python 微服务架构与 FastAPI 框架
Python 微服务架构与 FastAPI 框架

本专题系统讲解 Python 微服务架构设计与 FastAPI 框架应用,涵盖 FastAPI 的快速开发、路由与依赖注入、数据模型验证、API 文档自动生成、OAuth2 与 JWT 身份验证、异步支持、部署与扩展等。通过实际案例,帮助学习者掌握 使用 FastAPI 构建高效、可扩展的微服务应用,提高服务响应速度与系统可维护性。

7

2026.02.06

JavaScript 异步编程与事件驱动架构
JavaScript 异步编程与事件驱动架构

本专题深入讲解 JavaScript 异步编程与事件驱动架构,涵盖 Promise、async/await、事件循环机制、回调函数、任务队列与微任务队列、以及如何设计高效的异步应用架构。通过多个实际示例,帮助开发者掌握 如何处理复杂异步操作,并利用事件驱动设计模式构建高效、响应式应用。

11

2026.02.06

java连接字符串方法汇总
java连接字符串方法汇总

本专题整合了java连接字符串教程合集,阅读专题下面的文章了解更多详细操作。

47

2026.02.05

java中fail含义
java中fail含义

本专题整合了java中fail的含义、作用相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号