正文
在项目架构中,我们一般会分 控制层、逻辑层、数据层、服务层、展示层 等,每一层都只负责自己的业务,不混杂其它层逻辑在里面,
但是你会发现每一层都要对错误进行处理并返回错误内容(如查找内容为空,需返回内容不存在,而中断业务逻辑,无法继续向下运行返回真正的业务结果),
这就导致了每一层自己的业务中又混杂了有关错误的相关处理逻辑,使得这一层的逻辑不够纯粹,所以我们需要把错误相关处理也独立个 错误层 出来,
不过错误层与其他层是不一样的,会与其它层糅合在一起。这里你可能觉得有些奇怪,既然是独立怎么又会糅合在一起呢?换个角度想一下,我们在说话时,
我们还是可以听到其他人在说什么,你可能觉得我们的大脑是多线程的,事实上耳朵听到声音却只有一个感受器,只是大脑对不同频率的声波进行了业务处理。
我们这里也就是把错误的相关处理以另外一个频率传送出去,PHP提供了实现的方式,那就是错误捕获 try {} catch (\Throwable $e) {}
看一下完整示例,在入口层实现,把错误处理独立出来:
<?php
class A
{
public function actionProjectCreate()
{
try {
// ...
// 调用内层,内层抛出错误
throw new \RuntimeException("数据未找到", 400100);
// ...
} catch (\Throwable $e) {
$code = $e->getCode();
$msg = $e->getMessage();
$data = [];
// 错误位置描述
if (isset($xceptione_data)) {
$data = $xceptione_data;
}
echo json_encode(["code" => $code, "msg" => $msg, "data" => $data]);
}
}
}
返回信息:
{
"code": 3000011001,
"msg": "Undefined index: type",
"data": {
"msg": "file:/var/www/API/backend/controllers/ApiController.php,line:2334"
}
}
错误写入日志,这里也需要把日志层独立出来。
另外有一种思路就是在运行过程中用set_exception_handler()
、 set_error_handler()
、
register_shutdown_function()
注册 异常/错误/致命错误 处理函数,
这样程序会自助捕获异常错误并处理,这样在业务代码中就只有业务逻辑,而不会混入错误处理和日志记录的相关代码,现在Yii2实现了这种思路,
可以参考理解下。
PHP底层对异常错误的处理可以看下 这里。
参考资料
Yii2 异常及错误处理 https://ibaiyang.github.io/blog/yii2/2019/08/26/Yii2-异常及错误处理.html
PHP 异常及错误处理相关 https://ibaiyang.github.io/blog/php/2019/01/23/PHP-异常及错误处理相关.html