搜尋
首頁後端開發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');  //异常写日志

$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带来一些值得细细品味的精神食粮!

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

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
解釋負載平衡如何影響會話管理以及如何解決。解釋負載平衡如何影響會話管理以及如何解決。Apr 29, 2025 am 12:42 AM

負載均衡會影響會話管理,但可以通過會話複製、會話粘性和集中式會話存儲解決。 1.會話複製在服務器間複製會話數據。 2.會話粘性將用戶請求定向到同一服務器。 3.集中式會話存儲使用獨立服務器如Redis存儲會話數據,確保數據共享。

說明會話鎖定的概念。說明會話鎖定的概念。Apr 29, 2025 am 12:39 AM

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

有其他PHP會議的選擇嗎?有其他PHP會議的選擇嗎?Apr 29, 2025 am 12:36 AM

PHP會話的替代方案包括Cookies、Token-basedAuthentication、Database-basedSessions和Redis/Memcached。 1.Cookies通過在客戶端存儲數據來管理會話,簡單但安全性低。 2.Token-basedAuthentication使用令牌驗證用戶,安全性高但需額外邏輯。 3.Database-basedSessions將數據存儲在數據庫中,擴展性好但可能影響性能。 4.Redis/Memcached使用分佈式緩存提高性能和擴展性,但需額外配

在PHP的上下文中定義'會話劫持”一詞。在PHP的上下文中定義'會話劫持”一詞。Apr 29, 2025 am 12:33 AM

Sessionhijacking是指攻擊者通過獲取用戶的sessionID來冒充用戶。防範方法包括:1)使用HTTPS加密通信;2)驗證sessionID的來源;3)使用安全的sessionID生成算法;4)定期更新sessionID。

PHP的完整形式是什麼?PHP的完整形式是什麼?Apr 28, 2025 pm 04:58 PM

文章討論了PHP,詳細介紹了其完整形式,在We​​b開發中的主要用途,與Python和Java的比較以及對初學者的學習便利性。

PHP如何處理形式數據?PHP如何處理形式數據?Apr 28, 2025 pm 04:57 PM

PHP使用$ \ _ post和$ \ _獲取超級全局的php處理數據,並通過驗證,消毒和安全數據庫交互確保安全性。

PHP和ASP.NET有什麼區別?PHP和ASP.NET有什麼區別?Apr 28, 2025 pm 04:56 PM

本文比較了PHP和ASP.NET,重點是它們對大規模Web應用程序,性能差異和安全功能的適用性。兩者對於大型項目都是可行的,但是PHP是開源和無關的,而ASP.NET,

PHP是對病例敏感的語言嗎?PHP是對病例敏感的語言嗎?Apr 28, 2025 pm 04:55 PM

PHP的情況敏感性各不相同:功能不敏感,而變量和類是敏感的。最佳實踐包括一致的命名和使用對案例不敏感的功能進行比較。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器